第7篇:子查询是套娃术,层层嵌套才是高手!

52 阅读2分钟

🎬 套娃不只东北有,SQL 也讲"嵌套艺术"

还记得小时候买俄罗斯套娃吗?一层一层打开,最后才看到最小那个。
SQL 也有类似技巧:
在一个查询里套一个查询,再用这个结果干别的事
这,就是——子查询(Subquery)


1️⃣ 什么是子查询?

子查询就是嵌套在另一个 SELECTWHEREFROM 等语句中的查询。

SELECT *
FROM houses
WHERE price > (
  SELECT AVG(price)
  FROM houses
);

📌 这句的意思是
查出价格高于所有房源平均租金的房子


2️⃣ 子查询可以出现在哪些地方?

用法示例
WHERE比某个值大、小、存在等
IN值是否在一个列表中
SELECT嵌套来取值
FROM把子查询当作临时表

🧪 示例场景表:houses 房源表

house_idtitlepricedistrict
1精装一房1800天河
2电梯两房2500越秀
3合租三房2000天河
4豪华复式3600海珠
5简装单间1500越秀

3️⃣ 子查询 in WHERE:最常见

比平均租金贵的房子

SELECT * FROM houses
WHERE price > (
  SELECT AVG(price)
  FROM houses
);

在"天河区"的所有房源

SELECT * FROM houses
WHERE district IN (
  SELECT district
  FROM houses
  WHERE district = '天河'
);

(这个虽然看起来绕,其实更有用在多表操作中)


4️⃣ 子查询 in SELECT:搞清楚背景值

同时查出每套房 & 所有房的平均租金

SELECT title, price,
  (SELECT AVG(price) FROM houses) AS avg_price
FROM houses;

📌 每行都会多出一个"总平均租金"的对照列


5️⃣ 子查询 in FROM:虚拟表场景

先统计每个区的平均租金,再查出这些结果

SELECT *
FROM (
  SELECT district, AVG(price) AS avg_price
  FROM houses
  GROUP BY district
) AS district_avg
WHERE avg_price > 2000;

📌 像是在 SQL 里临时造了张统计表 district_avg 来操作


6️⃣ EXISTS:是否存在某些记录?

找出有房子的所有区(模拟"存在判断")

SELECT DISTINCT district
FROM houses h
WHERE EXISTS (
  SELECT 1 FROM houses WHERE h.district = district
);

🧠 子查询口诀

子查询像套娃,SELECT 里藏家家,
WHERE 后判断值,IN 后查名单,
FROM 中当临表,SELECT 出衬托他。

EXISTS 是问存不存在,AVG/MAX 比大小最精华。


🛠 小练习题

  1. 找出比平均租金高的房子

    SELECT * FROM houses
    WHERE price > (
      SELECT AVG(price) FROM houses
    );
    
  2. 查出租金最高房子的标题

    SELECT title FROM houses
    WHERE price = (
      SELECT MAX(price) FROM houses
    );
    
  3. 查询每套房的标题及全体平均租金

    SELECT title, price,
      (SELECT AVG(price) FROM houses) AS avg_price
    FROM houses;