PostgreSQL 子查询教程
子查询是嵌套在另一个查询中 的 SELECT。按返回结果可分为标量(单值)、行、表三类,常与 IN、ANY、ALL、EXISTS 配合使用。
本篇内容
- 标量子查询与行子查询
- IN / NOT IN 与子查询
- ANY / ALL 与比较运算符组合
- EXISTS / NOT EXISTS 与相关子查询
- 子查询 vs JOIN 的选型
标量子查询
-- 价格高于平均价的商品
SELECT id, name, price FROM products
WHERE price > (SELECT AVG(price) FROM products);
IN 与 EXISTS
-- IN:匹配子查询结果集合
SELECT id, name FROM users
WHERE id IN (SELECT user_id FROM orders WHERE amount > 1000);
-- EXISTS:只关心子查询是否有行,通常更快
SELECT id, name FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.amount > 1000
);
ANY / ALL
-- 至少比一个订单金额大
SELECT id, amount FROM orders
WHERE amount > ANY (SELECT amount FROM orders WHERE user_id = 1);
-- 比所有订单金额都大
SELECT id, amount FROM orders
WHERE amount > ALL (SELECT amount FROM orders WHERE user_id = 1);
待补充(TODO)
- 补充:相关子查询的执行模型(逐行求值)与性能注意点
- 补充:NOT IN 遇 NULL 的空结果陷阱及 NOT EXISTS 的替代写法
- 补充:FROM 子句中的派生表(inline view)与 LATERAL 连接
- 补充:子查询改写成 JOIN / CTE 的可读性与计划对比