12

我有两个带有单个键列的表。表 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 中。

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

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

4

4 回答 4

7

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

  SELECT b.key FROM b LEFT OUTER JOIN a ON b.key = a.key WHERE a.key IS NULL;
于 2014-11-03T02:49:20.860 回答
4

或者你可以试试

SELECT a.key FROM a LEFT ANTI JOIN b ON a.key = b.key
于 2015-06-30T17:53:17.623 回答
3

您的问题的答案应该是

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

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

于 2015-05-25T07:39:09.323 回答
1

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

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

于 2018-06-04T17:07:58.007 回答