[Hive]子查询使用指南

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的数据。
left join
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)

猜你喜欢

转载自blog.csdn.net/kaizuidebanli/article/details/115148157