嵌套查询(子查询,Subquery)在 SQL 中使用非常广泛,但也是最容易出错误的地方之一。下面按常见错误类型 + 原因 + 示例/解决方法来总结。
错误示例:
SELECT *
FROM employee
WHERE salary = (SELECT salary FROM employee WHERE dept_id = 10);
如果 dept_id = 10 有多名员工,子查询返回多行,就会报错:
SQL error: single-row subquery returns more than one row
解决方法:
IN 代替 =WHERE salary IN (SELECT salary FROM employee WHERE dept_id = 10);
WHERE salary = (SELECT MAX(salary) FROM employee WHERE dept_id = 10);
错误示例:
SELECT *
FROM employee
WHERE id IN (SELECT id FROM employee ORDER BY salary);
在 MySQL、Oracle 等中,普通子查询通常不允许 ORDER BY(除非配合 LIMIT/TOP)。
解决方法:
SELECT *
FROM employee
WHERE id IN (SELECT id FROM employee)
ORDER BY salary;
错误示例:
SELECT e.name
FROM employee e
WHERE e.salary > (
SELECT AVG(salary) FROM employee
);
虽然不报错,但如果想“按部门比较”,却忘了关联条件:
正确写法(相关子查询):
SELECT e.name
FROM employee e
WHERE e.salary > (
SELECT AVG(salary)
FROM employee
WHERE dept_id = e.dept_id
);
错误示例:
SELECT *
FROM employee
WHERE (id, salary) = (SELECT id FROM employee);
子查询只返回一列,但比较的是两列。
解决方法:
WHERE (id, salary) = (SELECT id, salary FROM employee WHERE ...);
错误示例:
SELECT
name,
(SELECT dept_name FROM department) AS dname
FROM employee;
如果 department 有多行,会直接报错。
解决方法:
SELECT
name,
(SELECT dept_name FROM department WHERE id = employee.dept_id)
FROM employee;
错误示例:
SELECT *
FROM employee
WHERE dept_id NOT IN (
SELECT dept_id FROM employee WHERE salary > 5000
);
如果子查询中有 NULL,NOT IN 结果可能全为空。
原因:
x NOT IN (1, 2, NULL) => UNKNOWN
解决方法:
WHERE dept_id NOT IN (
SELECT dept_id FROM employee WHERE salary > 5000 AND dept_id IS NOT NULL
);
NOT EXISTS常见误区:
IN:适合“值集合”EXISTS:适合“存在性判断”,尤其大表性能更好错误示例:
SELECT *
FROM employee e
WHERE e.dept_id IN (
SELECT 1 FROM department d WHERE d.id = e.dept_id
);
虽不报错,但语义不清晰,应改用 EXISTS。
错误示例:
SELECT dept_id
FROM employee
GROUP BY dept_id
HAVING COUNT(*) > (SELECT COUNT(*) FROM employee);
逻辑可能不成立(总数不可能小于分组数)。
建议:
嵌套过深容易导致:
推荐写法:
WITH dept_avg AS (
SELECT dept_id, AVG(salary) avg_sal
FROM employee
GROUP BY dept_id
)
SELECT e.name
FROM employee e
JOIN dept_avg d ON e.dept_id = d.dept_id
WHERE e.salary > d.avg_sal;
嵌套查询最常见错误是:行数不匹配、NULL 陷阱、逻辑关联错误、性能差。
如果你愿意,可以发一段你写的嵌套 SQL,我可以直接帮你指出问题并优化。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。