SQL子查询需按场景选用:WHERE后用单值/多值比较,FROM后用派生表实现分组Top N,EXISTS替代IN确保NULL安全,UPDATE/DELETE时用子查询绕开MySQL自引用限制。

SQL子查询不是“嵌套着写就完事”,关键在明确它解决什么问题、什么时候该用、怎么避免常见坑。下面直接按真实开发中最常遇到的几类场景,一步步拆解怎么写、为什么这么写、容易错在哪。
查“满足某条件的另一张表数据”——用WHERE + 子查询
比如:查出所有订单金额高于平均订单金额的客户姓名。
- 先算出平均订单金额:SELECT AVG(amount) FROM orders
- 再用这个结果筛选客户:SELECT name FROM customers WHERE id IN (SELECT customer_id FROM orders WHERE amount > (SELECT AVG(amount) FROM orders))
注意:子查询返回单值(如AVG)时,用>、=等比较符;返回多行(如customer_id列表)时,用IN或EXISTS,别用=,否则报错。
查“每个分组里的Top N”——用FROM + 子查询(派生表)
比如:查每个部门工资最高的员工(含部门名、姓名、工资)。
- 不能直接GROUP BY后SELECT *,会报错或结果错乱
- 正确做法:先把“各部门最高工资”查出来作为临时表,再和员工表JOIN
- SELECT d.name AS dept_name, e.name, e.salary FROM employees e JOIN (SELECT dept_id, MAX(salary) AS max_sal FROM employees GROUP BY dept_id) d_max ON e.dept_id = d_max.dept_id AND e.salary = d_max.max_sal JOIN departments d ON e.dept_id = d.id
这里子查询放在FROM后面,相当于创建一个虚拟表,必须起别名(如d_max),否则语法不通过。
判断“是否存在关联记录”——优先用EXISTS替代IN
比如:查所有有订单的客户(只关心“有没有”,不关心订单细节)。
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~