apache-hive / 3.1.1 / reference / Subqueries_in_SELECT.html

Problem

当前,Hive 不支持 SELECT 语句中的子查询,例如,以下查询将不会在 Hive 上运行:

SELECT customer.customer_num,
	(SELECT SUM(ship_charge)
		FROM orders
		WHERE customer.customer_num = orders.customer_num
	) AS total_ship_chg
FROM customer

最近,为扩展对子查询(HIVE-15456)的支持,已经完成了许多工作。但是这项工作主要针对扩展 WHERE 和 HAVING 子句中的子查询支持。我们计划 continue 在 HIVE-15456 中完成工作,以支持选择列表中的子查询(请参见HIVE-16091)。

Assumptions

我们计划通过以下假设和限制来限制范围。

  • 子查询只能是 SELECT 中的顶级表达式。也就是说,暂时将不支持复杂表达式,聚合,UDF 等中的子查询。例如,以下查询将不会在 Hive 上运行:

Not Supported

-- subquery in non-simple expression
SELECT 1 + (SELECT SUM(ship_charge) FROM orders), customer.customer_num FROM customer
 
-- subquery in CASE
SELECT CASE WHEN (select count(*) from store_sales 
                  where ss_quantity between 1 and 20) > 409437
            THEN (select avg(ss_ext_list_price) 
                  from store_sales 
                  where ss_quantity between 1 and 20) 
            ELSE (select avg(ss_net_paid_inc_tax)
                  from store_sales
                  where ss_quantity between 1 and 20) end bucket1
FROM reason
WHERE r_reason_sk = 1
  • 标量子查询最多只能返回一行。 Hive 将在运行时检查这种情况,如果不满意,则会抛出错误。例如,以下查询无效:

Not Supported

SELECT customer.customer_num,
	(SELECT ship_charge 
		FROM orders
		WHERE customer.customer_num = orders.customer_num
	) AS total_ship_chg
FROM customer
  • 标量子查询只能有一列。 Hive 将在编译过程中检查这种情况并抛出错误。例如,以下查询无效:

Not Supported

SELECT customer.customer_num,
	(SELECT ship_charge, customer_num
		FROM orders LIMIT 1
	) AS total_ship_chg
FROM customer
  • 仅在过滤器(即 WHERE 或 HAVING 子句)中允许使用相关变量。例如,以下查询无效:

Not Supported

SELECT customer.customer_num,
	(SELECT customer.customer_num 
		FROM orders
		WHERE customer.customer_num = orders.customer_num
	) AS total_ship_chg
FROM customer
  • 不允许使用 DISTINCT 的子查询。由于 DISTINCT<expression>将被评估为 GROUP BY<expression>,因此暂时不允许使用 DISTINCT 的子查询。

Design

给定以上假设,可以在 SELECT 中使用以下类型的子查询。

  • 标量子查询,例如:
SELECT customer.customer_num,
	(SELECT SUM(ship_charge) 
		FROM orders
		WHERE customer.customer_num = orders.customer_num
	) AS total_ship_chg
FROM customer
  • IN 子查询,例如:
SELECT p_size IN (
		SELECT MAX(p_size) FROM part)
FROM part
  • EXISTS 子查询,例如:
SELECT EXISTS(SELECT p_size FROM part)
FROM part

以上所有查询都可以是 相关不相关

其设计将类似于HIVE-15456中完成的工作。

  • genLogicalPlan 将遍历选择列表以执行以下操作:

  • 如果子查询不是顶级表达式,则引发错误。

    • 否则,通过使用 RexSubquery 代表子查询来生成适当的计划。
  • 然后将应用 HiveSubqueryRemoveRule 删除 RexSubquery 节点,并将查询重写为联接。

  • 然后,将使用 HiveRelDecorrelator :: decorrelateQuery 对相关查询进行解相关。

HIVE-16091介绍了支持 SELECT 中的子查询的初步工作。