子查询表达式
子查询可作为条件或标量值。相关子查询引用外层行,每个外层候选行都要按语义判断;优化器可改写执行方式,不应假定它逐行完整执行。
存在性:EXISTS
SELECT c.id
FROM customers AS c
WHERE EXISTS (
SELECT 1 FROM orders AS o
WHERE o.customer_id = c.id AND o.status = 'paid'
);
EXISTS 只看是否至少有一行,内部投影值通常无关紧要;NOT EXISTS 适合表达“没有关联行”。子查询的实际求值次数不保证,不要依赖其中有副作用的函数。
集合比较
SELECT id FROM products WHERE category_id IN (SELECT id FROM categories);
SELECT id FROM products WHERE price > ALL (SELECT price FROM discounts);
SELECT id FROM products WHERE price > ANY (SELECT price FROM discounts);
IN 类似逐项相等再求“或”,ANY/SOME 表示至少一次比较为真,ALL 表示所有比较都为真。空子查询使 ANY 为假、ALL 为真;NOT IN 遇到未匹配且结果含 NULL 时可能是未知,过滤可空值或使用正确关联的 NOT EXISTS。EXISTS 返回布尔值,IN 等比较还会受到三值逻辑影响。
标量与行子查询
SELECT p.id, (SELECT max(o.created_at) FROM orders AS o WHERE o.product_id = p.id) AS last_order
FROM products AS p;
标量子查询必须只返回一列且至多一行;零行得到 NULL,多行报错。聚合 max 可保证单行结果。也可以比较行:(a, b) = (SELECT x, y FROM ...),右侧仍须至多一行。不要用没有确定顺序的 LIMIT 1 随意压制多行错误;若确实只取一行,明确 ORDER BY 及并列处理策略。