Hive LEFT SEMI JOIN 表示“不存在”

Posted

技术标签:

【中文标题】Hive LEFT SEMI JOIN 表示“不存在”【英文标题】:Hive LEFT SEMI JOIN for 'NOT EXISTS' 【发布时间】:2014-07-30 15:37:22 【问题描述】:

我有两个表,只有一个键列。表 a 中的键是表 b 中所有键的子集。我需要从表 b 中选择不在表 a 中的键。

这是 Hive 手册的引文: “LEFT SEMI JOIN 以有效的方式实现了不相关的 IN/EXISTS 子查询语义。从 Hive 0.13 开始,使用子查询支持 IN/NOT IN/EXISTS/NOT EXISTS 运算符,因此大多数这些 JOIN 不必再手动执行. 使用 LEFT SEMI JOIN 的限制是右侧表只能在连接条件(ON 子句)中引用,而不能在 WHERE 或 SELECT 子句等中引用。"

他们用这个例子来说明:

    SELECT a.key, a.value FROM a WHERE a.key IN (SELECT b.key FROM B);

相当于

    SELECT a.key, a.val FROM a LEFT SEMI JOIN b ON (a.key = b.key);

但是,我需要做的是第一个带有 'NOT IN; 的示例。不幸的是,Hive 0.13 不支持这种语法。仅供参考:

    SELECT a.key, a.value FROM a WHERE a.key NOT IN (SELECT b.key FROM B);

我在这个网站上搜索了推荐,看到了这个例子:

    SELECT a.key FROM a LEFT OUTER JOIN b ON a.key = b.key WHERE b.key IS NULL;

它没有按预期工作。当我加入 a.key NOT in b 和 a.key IN b 时,我不会以这种方式获得原始 a。可能是因为这个查询不能解决问题,注意粗体文本 - b.key 不应该出现在 WHERE 中。

那我该怎么办?还有什么妙招?谢谢!

附:我不能分享任何真实数据;这是一个非常简单的例子,其中 a 中的键都包含在 b 中,而 a 是 b 的子集。

【问题讨论】:

在我知道的所有数据库中,not inleft joinis null 在功能上是等效的,假设比较值不是 NULL 谢谢,但我不明白这有什么帮助。什么是解查询? 。 .您的最后一个查询在功能上应该等同于 not in 版本(假设没有 NULL 值)。也许您可以编辑您的问题并解释它如何没有达到您的预期。我了解查询的工作原理。我不明白你的期望。 我解释了它如何在大型数据集上不起作用,但在简单数据上它可以正常工作。问题是:“还有其他方法可以满足我的需要吗?” 这是另一种解决方案。 SELECT key FROM (SELECT a.key, b1.marker FROM (SELECT key, COUNT(2) AS marker FROM b GROUP BY key) b1 RIGHT OUTER JOIN a ON b1.key = a.key) t WHERE marker IS NULL; 【参考方案1】:

如果您想要表 b 中的结果,也许您可​​以改为执行以下操作?

  SELECT b.key FROM b LEFT OUTER JOIN a ON b.key = a.key WHERE a.key IS NULL;

【讨论】:

我想要表 a 中的结果,而不是 b 中的结果,所以我无法从表 b 中选择任何内容。考虑表 b 是 IP 黑名单。我想从表 a 中选择所有内容,包括未列入黑名单的 IP。因此,连接在 IP 上作为键列。 @mel 您的问题清楚地表明您需要从表 b 中选择不在表 a 中的键。 OKK77 的答案可能是正确的答案。请接受!【参考方案2】:

或者你可以试试

SELECT a.key FROM a LEFT ANTI JOIN b ON a.key = b.key

【讨论】:

【参考方案3】:

你的问题的答案应该是

SELECT a.key FROM a LEFT OUTER JOIN b ON a.key = b.key WHERE b.key IS NULL;

这意味着,从 a 中取出所有键,而不管 b 中是否存在匹配项。 where 原因将过滤那些在 b 中不可用的记录。

【讨论】:

【参考方案4】:

我在 cdh 5.7.0 和 spark 1.6 版本中尝试了 IN 函数的左半连接。

半左连接给出了错误的结果,这与子查询中的IN函数不同。

【讨论】:

以上是关于Hive LEFT SEMI JOIN 表示“不存在”的主要内容,如果未能解决你的问题,请参考以下文章

hive 之 join 大法

hive join数据错误

INNER JOIN 和 LEFT SEMI JOIN 的区别

面试官:说说left join和left semi join 两者有什么区别?

HiveSql&SparkSql —— 使用left semi join做inexists类型子查询优化

SQL中left join on 、right join on、inner join on之间的区别