关联子查询就像"你问我答"的对话方式,其中内部查询(子查询)需要引用外部查询的信息才能回答问题。
生活化比喻
想象你在一个教室里:
- 外部查询:老师依次点名每个学生(比如:张三、李四、王五…)
- 子查询:被点名的学生要站起来回答:“我有没有交作业?”
这个"回答"过程就是关联子查询——每个学生(外部查询的每一行)被点名时,都要根据自己的情况(引用外部数据)回答一个问题。
主要特点
- 相互依赖:子查询需要用到外部查询的字段值才能执行
- 逐行处理:外部查询每检查一行数据,就要执行一次子查询
- 像过滤器:根据子查询的结果决定是否保留外部查询的当前行
简单示例
-- 找出有订单的客户
SELECT *
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id -- 这里引用了外部查询的c.id
);
这个查询的工作方式:
- 从customers表取一个客户
- 检查orders表是否有这个客户的订单(通过customer_id匹配)
- 如果有(EXISTS返回真),就保留这个客户
与非关联子查询的区别
非关联子查询:子查询可以独立运行,像一次性查好所有答案清单
SELECT *
FROM products
WHERE price > (SELECT AVG(price) FROM products); -- 子查询不依赖外部查询
关联子查询:子查询必须知道外部查询的当前行才能回答,像动态问答
SELECT *
FROM employees e
WHERE salary > (
SELECT AVG(salary)
FROM employees
WHERE department = e.department -- 需要知道e.department才能计算
);
为什么叫"关联"?
因为子查询和外部查询通过某些字段"关联"在一起(就像用绳子绑着),必须一起处理,不能分开单独执行。