Hive - 具有左外连接的 OR 条件
Posted
技术标签:
【中文标题】Hive - 具有左外连接的 OR 条件【英文标题】:Hive - OR condition with left outer join 【发布时间】:2018-01-16 10:48:23 【问题描述】:我已经参考了所有关于 SO 的类似案例的查询。尽管错误可能很常见,但我正在寻找针对特定情况的解决方案。请不要将问题标记为重复,除非您得到完全相同的方案和可接受的解决方案。
我有两张桌子
Main table:
c1 c2 c3 c4 c5
1 2 3 4 A
Other table
c1 c2 c3 c4 c5
1 8 5 6 B
8 2 8 9 C
8 7 3 9 C
8 7 9 4 C
5 6 7 8 D
现在,从另一个表中,我应该只能在所有列中选择唯一记录。例如仅最后一行 (5,6,7,8, D
)。
其他表的第 1 行被拒绝,因为 c1 值 (1) 与主表中的 c1 值 (1) 相同,第 2 行被拒绝,因为其他表和主表的 c2 值匹配,同样...
简而言之,在查询输出的主表中,其他表中的列都不应具有相同的值(在相应列中)。
我尝试在下面创建查询
select t1.* from otherTable t1
LEFT OUTER JOIN mainTable t2
ON ( t1.c1 = t2.c1 OR t1.c2 = t2.c2 OR t1.c3 = t2.c3 OR t1.c4 = t2.c4 )
Where t2.c5 is null;
但是,hive 会抛出异常
或目前在 JOIN 中不支持
我了解 hive 的限制,并且我多次使用 UNION (ALL | DISTINCT)
和内部连接来克服这个限制;但不能对此使用相同的策略。
请帮忙。
EDIT 1 : 我有 hive 版本限制 - 只能使用 1.2.0 版
【问题讨论】:
“只选择所有列中的唯一记录”是语言不清楚的片段。 “[the] 其他表中的任何列都不应在 [the] 主表中具有相同的值(在 [the] 对应列中)”很清楚。 (因此它不是“简而言之”,意思是不清楚和简洁,但希望有助于掌握或记住 其他一些描述 清晰。请花时间写下什么你的意思是让不知道你意思的人知道。像我们一样。当你说清楚时,你不必(模糊地)再说一遍。 【参考方案1】:您可以进行笛卡尔积连接(无条件的内连接):
select t1.* from otherTable t1
,mainTable t2
WHERE t1.c1 != t2.c1 AND t1.c2 != t2.c2
AND t1.c3 != t2.c3 AND t1.c4 != t2.c4 AND t1.c5 != t2.c5;
假设您在mainTable
中有一行,此查询应该与使用OUTER JOIN
的查询一样有效
另一种选择是将您提出的查询分成 5 个不同的LEFT OUTER JOIN
子查询:
select t1.* from (
select t1.* from (
select t1.* from (
select t1.* from (
select t1.* from otherTable t1
LEFT OUTER JOIN (select distinct c1 from mainTable) t2
ON ( t1.c1 = t2.c1) Where t2.c1 is null ) t1
LEFT OUTER JOIN (select distinct c2 from mainTable) t2
ON ( t1.c2 = t2.c2) Where t2.c2 is null ) t1
LEFT OUTER JOIN (select distinct c3 from mainTable) t2
ON ( t1.c3 = t2.c3) Where t2.c3 is null ) t1
LEFT OUTER JOIN (select distinct c4 from mainTable) t2
ON ( t1.c4 = t2.c4) Where t2.c4 is null ) t1
LEFT OUTER JOIN (select distinct c5 from mainTable) t2
ON ( t1.c5 = t2.c5) Where t2.c5 is null
;
在这里,对于每一列,我首先从mainTable
中获取不同的列,并将其与otherTable
的剩余部分连接起来。缺点是我通过了 5 次超过 mainTable
- 每列一次。如果主表中的值是唯一的,您可以从子查询中删除distinct
。
【讨论】:
由于 Hive 是一个仓库,因此假设它会有 TB 的数据,并且没有条件的内部连接不是一个可行的选择。如果这是唯一的解决方案,那么我最好编写一个 Map-Reduce 程序来处理数据并在输出时重新创建一个配置单元表。 @gyan 内部/交叉版本是您想要的明显表达。内部连接和交叉连接意味着相同的事情。甚至 Hive 也知道这一点。你为什么害怕内部/交叉连接?外部联接只是内部/交叉联接,它还添加了由空值扩展的不匹配的左表行。您已经期望 Hive 知道如何使用连接优化位置。 我不担心内部连接 [with a join condition],它根本无法解决这种特定情况。如果我没有得到它,请帮助我构建查询。交叉连接是不可行的,因为主表有 9.7 亿条(~5 TB)记录,而另一个表有 15 亿条记录(~7 TB),我们有一个时间窗口来处理它们。如果 hive 1.2.0 没有最优解,Hive UDF 或 MR 仍然是唯一的选择。 @gyan 添加了一个可能的解决方案,它可能在您的时间范围内有效。以上是关于Hive - 具有左外连接的 OR 条件的主要内容,如果未能解决你的问题,请参考以下文章
Hive sql中的 各种join(内连接左外连接右外连接满外连接)