Skip to content

SQL 子查询

概述

子查询(Subquery)是嵌套在其他 SQL 查询中的查询语句。子查询可以出现在 WHEREFROMSELECT 等子句中,使得复杂的数据检索逻辑可以在一条 SQL 语句中完成。

WHERE 子查询

IN 子查询

IN 用于检查某个值是否存在于子查询返回的结果集中:

sql
-- 查询属于"电子产品"分类的所有商品
SELECT * FROM products
WHERE category_id IN (
    SELECT id FROM categories WHERE name = '电子产品'
);

NOT IN 子查询

NOT IN 用于排除子查询返回结果中的值:

sql
-- 查询没有取消订单的用户
SELECT * FROM users
WHERE id NOT IN (
    SELECT user_id FROM orders WHERE status = 'cancelled'
);

EXISTS 子查询

EXISTS 用于检查子查询是否返回至少一行数据:

sql
-- 查询至少有一笔订单的用户
SELECT * FROM users u
WHERE EXISTS (
    SELECT 1 FROM orders o WHERE o.user_id = u.id
);

NOT EXISTS 子查询

NOT EXISTS 用于检查子查询是否不返回任何数据:

sql
-- 查询没有任何评价的商品
SELECT * FROM products p
WHERE NOT EXISTS (
    SELECT 1 FROM reviews r WHERE r.product_id = p.id
);

FROM 子查询(派生表)

子查询可以放在 FROM 子句中作为临时表使用:

sql
-- 查询商品数量超过10的分类统计信息
SELECT * FROM (
    SELECT
        category,
        COUNT(*) AS product_count,
        AVG(price) AS avg_price
    FROM products
    GROUP BY category
) AS category_stats
WHERE product_count > 10;

SELECT 子查询(标量子查询)

子查询可以放在 SELECT 子句中,作为计算列使用:

sql
-- 查询每个用户及其订单数量
SELECT
    name,
    (SELECT COUNT(*) FROM orders WHERE user_id = users.id) AS order_count
FROM users;

相关子查询

相关子查询引用了外部查询的列,每处理外部查询的一行数据,子查询都会重新执行一次:

sql
-- 查询每个分类中价格最高的商品
SELECT p.* FROM products p
WHERE p.price = (
    SELECT MAX(price)
    FROM products
    WHERE category = p.category
);

小结

子查询要点:

  • WHERE 子句中可使用 INEXISTS 等操作符
  • FROM 子句中的子查询作为派生表使用
  • SELECT 子句中的标量子查询用于计算列
  • 相关子查询引用外部查询的列