温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

嵌套查询语法要注意啥

发布时间:2026-10-13 07:55:08 来源:亿速云 阅读:97 作者:小樊 栏目:数据库

嵌套查询(Subquery / Nested Query,也叫子查询)在 SQL 里非常常见,但写的时候容易踩坑。下面从语法规则、常见错误、性能与书写建议几个角度总结要注意的点。


一、基本语法注意点

1. 子查询必须用括号 () 包起来

SELECT *
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

❌ 忘记括号会直接报错。


2. 子查询位置不同,规则不同

常见位置:

  • WHERE 子句
  • FROM 子句(派生表)
  • SELECT 子句(标量子查询)
  • HAVING 子句

FROM 中的子查询必须起别名

SELECT t.avg_sal
FROM (SELECT AVG(salary) AS avg_sal FROM employees) t;

❌ 不起别名在标准 SQL 中是不允许的。


二、返回值数量要匹配

1. 单行子查询 vs 多行子查询

使用场景 运算符 子查询返回
单行 = > < >= 只能一行一列
多行 IN ANY ALL 多行一列

❌ 错误示例:

SELECT *
FROM emp
WHERE deptno = (SELECT deptno FROM dept);

如果子查询返回多行,会报:

single-row subquery returns more than one row

✅ 正确:

WHERE deptno IN (SELECT deptno FROM dept);

2. SELECT 中的子查询必须是“标量子查询”

SELECT name,
       (SELECT MAX(salary) FROM employees) AS max_sal
FROM departments;

❌ 不能返回多行或多列。


三、NULL 值陷阱(非常重要)

NOT IN + NULL = 永远无结果

WHERE id NOT IN (SELECT manager_id FROM emp);

如果 manager_id 中有 NULL,结果可能是空集。

✅ 更安全写法:

WHERE id NOT IN (
  SELECT manager_id FROM emp WHERE manager_id IS NOT NULL
);

或用 NOT EXISTS。


四、相关性子查询(Correlated Subquery)

子查询依赖外层查询:

SELECT e.name
FROM emp e
WHERE salary > (
  SELECT AVG(salary)
  FROM emp
  WHERE deptno = e.deptno
);

⚠️ 注意:

  • 执行次数 = 外层行数
  • 性能通常较差
  • 可用 JOIN 或窗口函数优化

五、性能与可读性原则

1. 能用 JOIN 就少用嵌套

-- 不推荐
SELECT *
FROM emp
WHERE deptno IN (SELECT deptno FROM dept WHERE loc='NY');

-- 推荐
SELECT e.*
FROM emp e
JOIN dept d ON e.deptno = d.deptno
WHERE d.loc = 'NY';

2. 深层嵌套可读性差

超过 3 层嵌套,建议:

  • 拆成 CTE(WITH)
  • 或临时表
WITH avg_sal AS (
  SELECT deptno, AVG(salary) s
  FROM emp
  GROUP BY deptno
)
SELECT *
FROM emp e
JOIN avg_sal a ON e.deptno = a.deptno
WHERE e.salary > a.s;

六、数据库差异注意

  • MySQL:早期版本不支持 FROM 子查询索引优化
  • Oracle:相关子查询很常见
  • PostgreSQL:CTE 默认不物化(可能影响性能)

一句话总结

括号不能少、返回行数要匹配、NULL 要小心、相关子查询慎用、能用 JOIN/CTE 就别嵌套太深。

如果你有具体数据库(MySQL / Oracle / PG)或具体 SQL 报错,我可以帮你逐句改。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手