产品概述
应用场景
产品架构
实例类型
兼容性说明
使用规范建议
SELECTc_name,c_acctbal,(SELECT AVG(c_acctbal) FROM customer) AS avg_balanceFROM customerLIMIT 5;
FROM 子句中的子查询,作为一个临时表参与后续查询。其关键特征是子查询必须用括号包裹并指定别名。SELECT seg.c_mktsegment, seg.cntFROM (SELECT c_mktsegment, COUNT(*) AS cntFROM customerGROUP BY c_mktsegment) segORDER BY seg.cnt DESC;
EXISTS、NOT EXISTS、IN、NOT IN 等关键字判断子查询是否返回数据,结果是布尔值。其关键特征是不关心子查询返回的具体值,只关心是否有行存在。-- EXISTS:判断是否存在匹配行SELECT c_name FROM customer cWHERE EXISTS (SELECT 1 FROM orders o WHERE o.o_custkey = c.c_custkey);-- IN:判断值是否在结果集中SELECT c_name FROM customerWHERE c_nationkey IN (SELECT n_nationkey FROM nation WHERE n_name = 'CHINA');
ANY、ALL、SOME 关键字将一个值与子查询返回的结果集进行比较。其关键特征是比较运算符(=、>、< 等)与 ANY/ALL 组合使用。-- = ANY 等价于 INSELECT c_name, c_acctbal FROM customerWHERE c_acctbal > ANY (SELECT o_totalprice FROM orders WHERE o_orderstatus = 'F');-- > ALL:大于子查询返回的所有值SELECT c_name, c_acctbal FROM customerWHERE c_acctbal > ALL (SELECT AVG(c_acctbal) FROM customer GROUP BY c_mktsegment);
>、<、=、>=、<=、<>)的一侧操作数。其关键特征是子查询必须返回单行单列(即标量),与标量子查询的区别在于它出现在 WHERE/HAVING 的比较条件中。SELECT o_orderkey, o_totalpriceFROM ordersWHERE o_totalprice > (SELECT AVG(o_totalprice) FROM orders);
SELECT c_custkey, c_name, c_acctbalFROM customerWHERE c_acctbal > (SELECT AVG(c_acctbal) FROM customer);
SELECT AVG(c_acctbal) FROM customer;
4990.51,则外层查询等价于:SELECT c_custkey, c_name, c_acctbalFROM customerWHERE c_acctbal > 4990.51;
SELECT c_custkey, c_name, c_mktsegmentFROM customerWHERE c_custkey IN (SELECT DISTINCT o_custkey FROM ordersWHERE o_orderdate >= '1995-01-01');
o_custkey 值,外层查询在这组值中进行匹配。SELECT o_orderkey, o_custkey, o_totalprice, o_orderdateFROM orders o1WHERE o_totalprice = (SELECT MAX(o2.o_totalprice)FROM orders o2WHERE o2.o_custkey = o1.o_custkey);
o1.o_custkey,对于外层每一行,子查询计算该客户的最大订单金额,然后只保留金额等于最大值的行。SELECT c1.c_custkey, c1.c_name, c1.c_mktsegment, c1.c_acctbalFROM customer c1WHERE c1.c_acctbal > (SELECT AVG(c2.c_acctbal)FROM customer c2WHERE c2.c_mktsegment = c1.c_mktsegment);
SELECT c1.c_custkey, c1.c_name, c1.c_mktsegment, c1.c_acctbalFROM customer c1INNER JOIN (SELECT c_mktsegment, AVG(c_acctbal) AS avg_acctbalFROM customerGROUP BY c_mktsegment) c2 ON c1.c_mktsegment = c2.c_mktsegmentWHERE c1.c_acctbal > c2.avg_acctbal;
customer 表扫描两次(一次聚合、一次连接),而不是对每个客户都执行一次子查询,性能显著提升。EXISTS 用于判断子查询是否返回了至少一行数据,常用于存在性检查。SELECT c.c_custkey, c.c_name, c.c_acctbalFROM customer cWHERE EXISTS (SELECT 1 FROM orders oWHERE o.o_custkey = c.c_custkeyAND o.o_totalprice > 300000);
SELECT c.c_custkey, c.c_name, c.c_phoneFROM customer cWHERE NOT EXISTS (SELECT 1 FROM orders oWHERE o.o_custkey = c.c_custkey);
NOT EXISTS 在语义上等价于 LEFT JOIN ... WHERE ... IS NULL,但在某些场景下两者的执行效率不同,可通过 EXPLAIN 进行比较。IN 用于判断某个值是否在子查询返回的结果集中。SELECT c_custkey, c_name, c_nationkeyFROM customerWHERE c_nationkey IN (SELECT n_nationkey FROM nationWHERE n_regionkey IN (SELECT r_regionkey FROM regionWHERE r_name = 'ASIA'));
IN 和 EXISTS 性能差异不大;当外层表较小而子查询结果集较大时,EXISTS 通常更高效。SELECT 列表、WHERE 条件等位置。SELECTo_orderkey,o_totalprice,o_orderdate,(SELECT c_name FROM customer WHERE c_custkey = o_custkey) AS customer_nameFROM ordersWHERE o_orderdate = '1995-03-15';
SELECTo.o_orderkey,o.o_totalprice,o.o_orderdate,c.c_name AS customer_nameFROM orders oINNER JOIN customer c ON o.o_custkey = c.c_custkeyWHERE o.o_orderdate = '1995-03-15';
FROM 子句中作为临时表(派生表)使用。SELECT c.c_custkey, c.c_name, c.c_mktsegment, c.c_acctbalFROM customer cINNER JOIN (SELECT c_mktsegment, MAX(c_acctbal) AS max_acctbalFROM customerGROUP BY c_mktsegment) seg_max ON c.c_mktsegment = seg_max.c_mktsegmentAND c.c_acctbal = seg_max.max_acctbal;
SELECT *FROM (SELECTo_orderpriority,COUNT(*) AS order_count,AVG(o_totalprice) AS avg_amountFROM ordersGROUP BY o_orderpriority) summaryWHERE order_count > 10000ORDER BY order_count DESC;
文档反馈