1、在from语句中使用子查询
Hive在0.12版本后就支持了from条件中子查询,例如:
SELECT ... FROM (subquery) name ...
SELECT ... FROM (subquery) AS name ... (Note: Only valid starting with Hive 0.13.0)
但是在from语句中使用子查询,必须给子查询一个名称,因为 FROM 子句中的每个表都必须有一个名称。
子查询选择列表中的列必须具有唯一的名称。子查询选择列表中的列在外部查询中可用,就像正常表的列一样。
简单子查询的示例:
SELECT col
FROM (
SELECT a+b AS col
FROM t1
) t2
子查询也可以是带有 UNION 的查询表达式。 Hive 支持任意级别的子查询。
SELECT t3.col
FROM (
SELECT a+b AS col
FROM t1
UNION ALL
SELECT c+d AS col
FROM t2
) t3
Hive 0.13.0 和更高版本(HIVE-6519)中的子查询名称之前可以包含可选关键字“AS”。
2、在where子句中使用子查询
0.13版本后就支持了where条件中的子查询,前提是对于in、not in这样的子查询(也叫做’不相关子查询’,因为不会引用到父查询的列),查询结果必须被当作是个常量。
SELECT *
FROM A
WHERE A.a IN (SELECT foo FROM B);
也同样支持 EXISTS 和 NOT EXISTS 类型的子查询:
SELECT A
FROM T1
WHERE EXISTS (SELECT B FROM T2 WHERE T1.X = T2.Y)
我们在使用子查询的时候存在一些限制条件:
1、 仅在表达式的右侧支持这些子查询。
2、 IN/NOT IN 子查询只能选择一个列。
3、 EXISTS/NOT EXISTS 必须具有一个或多个相关谓词。
4、 仅在子查询的 WHERE 子句中支持对父查询的引用。
3、子查询的替代方式
Hive对子查询的支持有限,我们在实际的使用过程中可能因为逻辑较为复杂或者是Hive版本不支持等原因,那么我们需要换种方式进行解决。
问题:查询没有选修数学的学生信息。
3.1 使用left join
我们使用韦恩图形象的描述,取不在表b中的表a的数据。
SQL实现:
select id,name
from student s
left join
(
SELECT
cid
FROM math_course
) c
WHERE c.cid is null
3.2 使用not exists
SELECT id,name
FROM student s
WHERE NOT EXISTS (SELECT cid FROM math_course c WHERE s.id = c.cid)