Hive LEFT SEMI JOIN加入'NOT EXISTS'

mel*_*mel 10 sql hive semi-join hiveql

我有两个表有一个单键列.表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);
Run Code Online (Sandbox Code Playgroud)

相当于

    SELECT a.key, a.val FROM a LEFT SEMI JOIN b ON (a.key = b.key);
Run Code Online (Sandbox Code Playgroud)

但是,我需要做的是第一个带'NOT IN;的例子.不幸的是,Hive 0.13不支持这种语法.这仅用于说明:

    SELECT a.key, a.value FROM a WHERE a.key NOT IN (SELECT b.key FROM B);
Run Code Online (Sandbox Code Playgroud)

我搜索了这个网站的建议,看到了这个例子:

    SELECT a.key FROM a LEFT OUTER JOIN b ON a.key = b.key WHERE b.key IS NULL;
Run Code Online (Sandbox Code Playgroud)

它没有按预期工作.当我加入a.key而不是b和a.key IN b时,我不会这样得到原文.也许那是因为这个查询无法做到这一点,注意粗体文本 - b.key不应该出现在WHERE中.

那我该怎么办?还有其他技巧吗?谢谢!

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

小智 6

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

  SELECT b.key FROM b LEFT OUTER JOIN a ON b.key = a.key WHERE a.key IS NULL;
Run Code Online (Sandbox Code Playgroud)

  • 我想要表a的结果,而不是b,所以我不能从表b中选择任何东西.考虑表b是IP的黑名单.我想从包括IP的表格中选择所有内容,而不是列入黑名单.因此,连接在IP上作为键列. (2认同)

小智 5

或者你可以尝试

SELECT a.key FROM a LEFT ANTI JOIN b ON a.key = b.key
Run Code Online (Sandbox Code Playgroud)