在 Hive 或 Impala 或 Pig 中通过字符串匹配加入 table
Join table by string matching in Hive or Impala or Pig
我有两个表 A
和 B
,其中 B
很大(2000 万 x 300)而 A
中等大小(300k x 10) . A
包含一列地址,B
包含 3 列,可以将它们放在一起形成正确的街道地址。例如,在 A
中,地址列可以是:
id | Address
-----------
233 | 123 Main St
在B
中我们可以:
Number | Street_name | Street_suffix | Tax
------------------------------------------------
123 | Main | Street | 320.2
我想使用类似于 LIKE
的字符串匹配加入他们,如下所示:
select A.id, B.Tax
from A
left join B
on A.Address **contains** B.Number
and A.Address **contains** B.Street_name;
基本上我试图通过说如果 A
的地址包含 B
的号码和 street_name 来匹配记录,那么我说它们是相同的地址(实际上,我也有城市、州和邮政编码。但出于说明目的,我选择忽略它们)。
2 contains 部分是我不确定如何实现的部分。有什么想法吗?
我在 Cloudera 的 Hue Hadoop 发行版上,在那里我可以访问 Hive(1.1.0,不幸的是因为 1.2.0 具有 Levenshtein 距离函数),Impala (v2.3.0) 和 Pig (0.12. 0-cdh5.5.0).
Hive 连接有限制,您只能使用具有相等条件的连接。
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Joins
如果您可以在逻辑上分解 A.Address 列以匹配 table B 列格式,那么您可以对该列使用连接....
您只能使用具有相等条件的连接,但是 -
您可以 cross join 和 filter.
select A.id, B.Tax
from A cross join B
where concat(' ',A.Address,' ') like concat('% ',cast(B.Number as string),' %')
and concat(' ',A.Address,' ') like concat('% ',B.Street_name,' %')
;
演示
hive> create table A (id int,Address string);
OK
hive> create table B (number int,Street_name string,Street_suffix string,tax decimal(12,2));
OK
hive> insert into A values (233,'123 Main St');
Query ID = ...
OK
hive> insert into B values (123,'Main','Street',320.2);
Query ID = ...
OK
hive> select A.id, B.Tax
> from A cross join B
> where concat(' ',A.Address,' ') like concat('% ',cast(B.Number as string),' %')
> and concat(' ',A.Address,' ') like concat('% ',B.Street_name,' %')
> ;
Warning: Map Join MAPJOIN[8][bigTable=b] in task 'Stage-3:MAPRED' is a cross product
Query ID = ...
OK
233 320.2
hive>
首先,Hive 中的 JOIN 仅适用于相等条件
所以你可以像下面这样用 like 和 concat 操作来尝试 where 条件
select A.id, B.Tax
from A,B where A.Address LIKE CONCAT('%',cast(B.Number as string),'%')
AND
A.Address LIKE CONCAT('%',B.Street_name,'%')
我有两个表 A
和 B
,其中 B
很大(2000 万 x 300)而 A
中等大小(300k x 10) . A
包含一列地址,B
包含 3 列,可以将它们放在一起形成正确的街道地址。例如,在 A
中,地址列可以是:
id | Address
-----------
233 | 123 Main St
在B
中我们可以:
Number | Street_name | Street_suffix | Tax
------------------------------------------------
123 | Main | Street | 320.2
我想使用类似于 LIKE
的字符串匹配加入他们,如下所示:
select A.id, B.Tax
from A
left join B
on A.Address **contains** B.Number
and A.Address **contains** B.Street_name;
基本上我试图通过说如果 A
的地址包含 B
的号码和 street_name 来匹配记录,那么我说它们是相同的地址(实际上,我也有城市、州和邮政编码。但出于说明目的,我选择忽略它们)。
2 contains 部分是我不确定如何实现的部分。有什么想法吗?
我在 Cloudera 的 Hue Hadoop 发行版上,在那里我可以访问 Hive(1.1.0,不幸的是因为 1.2.0 具有 Levenshtein 距离函数),Impala (v2.3.0) 和 Pig (0.12. 0-cdh5.5.0).
Hive 连接有限制,您只能使用具有相等条件的连接。
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Joins
如果您可以在逻辑上分解 A.Address 列以匹配 table B 列格式,那么您可以对该列使用连接....
您只能使用具有相等条件的连接,但是 -
您可以 cross join 和 filter.
select A.id, B.Tax
from A cross join B
where concat(' ',A.Address,' ') like concat('% ',cast(B.Number as string),' %')
and concat(' ',A.Address,' ') like concat('% ',B.Street_name,' %')
;
演示
hive> create table A (id int,Address string);
OK
hive> create table B (number int,Street_name string,Street_suffix string,tax decimal(12,2));
OK
hive> insert into A values (233,'123 Main St');
Query ID = ...
OK
hive> insert into B values (123,'Main','Street',320.2);
Query ID = ...
OK
hive> select A.id, B.Tax
> from A cross join B
> where concat(' ',A.Address,' ') like concat('% ',cast(B.Number as string),' %')
> and concat(' ',A.Address,' ') like concat('% ',B.Street_name,' %')
> ;
Warning: Map Join MAPJOIN[8][bigTable=b] in task 'Stage-3:MAPRED' is a cross product
Query ID = ...
OK
233 320.2
hive>
首先,Hive 中的 JOIN 仅适用于相等条件
所以你可以像下面这样用 like 和 concat 操作来尝试 where 条件
select A.id, B.Tax
from A,B where A.Address LIKE CONCAT('%',cast(B.Number as string),'%')
AND
A.Address LIKE CONCAT('%',B.Street_name,'%')