根据Hive的documentation,它支持NOT IN
子句中的WHERE
子查询,条件是子查询是不相关的子查询(不引用主查询中的列)。
但是,当我尝试运行下面的琐碎查询时,出现错误FAILED: SemanticException Cartesian products are disabled for safety reasons.
-- sample data
CREATE TEMPORARY TABLE foods (name STRING);
CREATE TEMPORARY TABLE vegetables (name STRING);
INSERT INTO foods VALUES ('steak'), ('eggs'), ('celery'), ('onion'), ('carrot');
INSERT INTO vegetables VALUES ('celery'), ('onion'), ('carrot');
-- the problematic query
SELECT *
FROM foods
WHERE foods.name NOT IN (SELECT vegetables.name FROM vegetables)
请注意,如果我使用IN
子句而不是NOT IN
子句,它实际上可以正常工作,这很令人困惑,因为在任何情况下查询评估结构都应该相同。
是否有解决方法,或者是基于值在另一个表中从查询中筛选值的另一种方法?
这是在Amazon EMR集群上运行的Hive 2.3.4 btw。
答案 0 :(得分:1)
不确定为什么会收到该错误。一种解决方法是使用not exists
。
SELECT f.*
FROM foods f
WHERE NOT EXISTS (SELECT 1
FROM vegetables v
WHERE v.name = f.name)
或left join
SELECT f.*
FROM foods f
LEFT JOIN vegetables v ON v.name = f.name
WHERE v.name is NULL
答案 1 :(得分:0)
您获得了笛卡尔加入,因为这是Hive在这种情况下所做的。 vegetables
表很小(仅一行),正在广播以执行交叉(很可能是map-join,检查计划)连接。 Hive会先交叉(映射)连接,然后应用过滤器。带有@VamsiPrabhala表示的过滤器的显式左联接语法将强制执行左联接,但是在这种情况下,它的作用相同,因为表非常小,并且CROSS JOIN不会将行相乘。
对查询执行EXPLAIN,您将看到实际发生的情况。