子查询是嵌套在另一个查询中的查询——用于 WHERE、FROM、SELECT 或与 EXISTS 一起。它允许你在另一个查询中使用一个查询的结果,从而实现复杂的过滤和计算。
WHERE 中的子查询——根据另一个查询的结果进行过滤
sql
name users
id ( user_id orders);
name, price products
price ( (price) products);
子查询是嵌套在另一个查询中的查询——用于 WHERE、FROM、SELECT 或与 EXISTS 一起。它允许你在另一个查询中使用一个查询的结果,从而实现复杂的过滤和计算。
name users
id ( user_id orders);
name, price products
price ( (price) products);
WHERE 中的子查询提供用于过滤的值——一个列表(带 IN)或单个值(带比较运算符)。
-- for each user, find those with above-average orders FOR THEIR COUNTRY
SELECT name FROM users u
WHERE order_count > (
SELECT AVG(order_count) FROM users
WHERE country = u.country -- references the OUTER query's row (correlated)
);
相关子查询引用外部查询——它对每个外部行运行一次(可能较慢)。非相关子查询运行一次。
-- users who have at least one order (often more efficient than IN)
SELECT name FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o WHERE o.user_id = u.id -- just checks existence
);
EXISTS 检查子查询是否返回任何行——通常比 IN 对存在性检查更高效(它可以在第一个匹配处停止)。
-- use a subquery result as a table
SELECT country, avg_age FROM (
SELECT country, AVG(age) AS avg_age FROM users GROUP BY country
) AS country_stats
WHERE avg_age > 30;
Many subqueries can be rewritten as JOINs (often more efficient/readable).
WHERE id IN (SELECT ...) → can often be a JOIN
Use subqueries for clarity in filtering/aggregation; JOINs for combining data.
CTEs (WITH) are often a cleaner alternative to complex nested subqueries.
子查询是一项重要的 SQL 技术,用于复杂查询——在另一个查询中使用一个查询的结果可以实现简单查询无法表达的过滤和计算,因此理解它们对编写真实查询很有价值。
了解这些形式——WHERE 中的子查询(使用 IN 按列表过滤或使用比较按单个值过滤)、相关子查询(引用外部查询,每行运行一次)、EXISTS(高效存在性检查)和 FROM 中的子查询(派生表)——涵盖了表达复杂逻辑的常见模式。
理解相关和非相关子查询之间的区别对于性能很重要(相关子查询每行运行一次外部行,可能很慢)。
同样有价值的是了解与 JOIN 和 CTE 的关系:许多子查询可以重写为 JOIN(通常更高效和可读)或 CTE(对于复杂情况更简洁),因此理解何时使用每种方法——子查询用于过滤/聚合清晰度,JOIN 用于组合数据——是一项实用技能。
由于真实世界的查询通常需要嵌套(按聚合结果过滤、存在性检查、与计算值比较),并且由于理解子查询、它们的性能特征(尤其是相关的)以及它们与 JOIN/CTE 的关系对于编写有效的、高效的复杂查询很重要,掌握子查询是 SQL 中超越基本查询的宝贵的、频繁应用的知识,也是一个常见的面试主题,展示了表达复杂数据需求的能力。