Z
ZHANK
子查询与CTE

子查询基础

掌握 WHERE 中子查询、IN/EXISTS/ANY/ALL

子查询基础

一个查询的结果作为另一个查询的输入——这就是子查询。它让你把复杂问题拆成简单步骤。

学完本章你将: 掌握 WHERE 子查询、IN/EXISTS、关联子查询。


子查询在 WHERE 中

sql
-- 查年龄大于平均年龄的用户
SELECT name, age FROM users
WHERE age > (SELECT AVG(age) FROM users);
-- 括号里的先执行,结果给外层用

IN —— 多值子查询

sql
-- 查有订单的用户
SELECT name FROM users
WHERE id IN (SELECT DISTINCT user_id FROM orders);

IN 后面的子查询可以返回多行,外层检查"id 是否在这个集合里"。


EXISTS —— 比 IN 更高效

EXISTS 检查子查询有没有结果,不是检查具体值。只要有一条就返回 true。

sql
-- 同样查有订单的用户(EXISTS 通常比 IN 快)
SELECT name FROM users u
WHERE EXISTS (
    SELECT 1 FROM orders o WHERE o.user_id = u.id
);

💡 EXISTS vs IN: EXISTS 检查"存在",找到第一条就停(相关子查询优化)。IN 需要把子查询结果全算出来再比较。数据量大时 EXISTS 明显更快。


关联子查询 —— 子查询引用外层列

sql
-- 查订单金额高于该用户平均金额的订单
SELECT * FROM orders o1
WHERE amount > (
    SELECT AVG(amount) FROM orders o2
    WHERE o2.user_id = o1.user_id   -- 引用外层!
);

关联子查询每行都要执行一次子查询(内部引用了外层的值),大量数据时会很慢。