🎬 套娃不只东北有,SQL 也讲"嵌套艺术"
还记得小时候买俄罗斯套娃吗?一层一层打开,最后才看到最小那个。
SQL 也有类似技巧:
在一个查询里套一个查询,再用这个结果干别的事。
这,就是——子查询(Subquery)!
1️⃣ 什么是子查询?
子查询就是嵌套在另一个 SELECT、WHERE、FROM 等语句中的查询。
SELECT *
FROM houses
WHERE price > (
SELECT AVG(price)
FROM houses
);
📌 这句的意思是:
查出价格高于所有房源平均租金的房子
2️⃣ 子查询可以出现在哪些地方?
| 用法 | 示例 |
|---|---|
WHERE 中 | 比某个值大、小、存在等 |
IN | 值是否在一个列表中 |
SELECT 中 | 嵌套来取值 |
FROM 中 | 把子查询当作临时表 |
🧪 示例场景表:houses 房源表
| house_id | title | price | district |
|---|---|---|---|
| 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 比大小最精华。
🛠 小练习题
-
找出比平均租金高的房子
SELECT * FROM houses WHERE price > ( SELECT AVG(price) FROM houses ); -
查出租金最高房子的标题
SELECT title FROM houses WHERE price = ( SELECT MAX(price) FROM houses ); -
查询每套房的标题及全体平均租金
SELECT title, price, (SELECT AVG(price) FROM houses) AS avg_price FROM houses;