EXISTS
EXISTS 判断子查询是否有结果——有就返回 TRUE,没有就 FALSE。和 IN 不同,EXISTS 不关心子查询返回什么值,只关心"有还是没有"。它的执行方式是逐行检查外层表的每一行,看子查询能不能找到匹配——找到一条立即停,不等子查询跑完。
EXISTS 常用于关联子查询:子查询里引用外层表的列,形成"对每一行外层数据,去内层表里搜一遍"。这种查询模式在"找出有过某些行为的对象"场景下非常高效——比如"有过订单的客户""领过奖金的员工"。
EXISTS 和 IN 在逻辑上有重叠,但有细微差异:NOT EXISTS 处理 NULL 的行为比 NOT IN 更可靠——NOT IN 遇到子查询结果含 NULL 时整个查询返回空,而 NOT EXISTS 不受影响。
以飞翔科技为例:
-- 查有过绩效奖金的员工
SELECT emp_name, basic_salary
FROM employees e
WHERE EXISTS (
SELECT 1 FROM bonus_records b
WHERE b.emp_id = e.emp_id
);
-- 查在飞翔小店下过单的客户
SELECT customer_name, customer_email
FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.customer_id
AND o.shop_name = '飞翔小店'
);
-- 查没有任何奖金的员工
SELECT emp_name, dept_code
FROM employees e
WHERE NOT EXISTS (
SELECT 1 FROM bonus_records b
WHERE b.emp_id = e.emp_id
);
子查询里的 SELECT 1 是一个习惯——因为 EXISTS 不看返回值,返回什么列无所谓,1 就够了,数据库也对此做了优化。