本文共 2027 字,大约阅读时间需要 6 分钟。
在 SQL 语句中,子查询是一种常见的技术,用于在一个主查询中嵌套另一个查询。子查询可以支持多层嵌套,根据不同的位置和结果类型,子查询又可以分为标量子查询、列子查询、行子查询和表子查询等多种形式。本文将详细介绍子查询的分类、特点以及实际应用场景。
子查询的位置在主查询中有不同的意义:
在 select
语句后面:仅支持标量子查询,用于单个值的比较。
在 from
语句后面:支持表子查询,用于从另一个表中获取数据。
在 where
或 having
后面:支持标量子查询(用于单个值比较)、列子查询(用于多行比较)以及行子查询(用于单行多列比较)。
在 exists
后面:用于判断子查询是否存在结果,使用较少。
标量子查询:结果集为单行单列,通常用于与单值比较操作符(如 >
, <
, =
等)搭配使用。
列子查询:结果集为单列多行,通常用于与多值比较操作符(如 in
, not in
, any
, all
等)搭配使用。
行子查询:结果集为单行多列,用于单行数据的多列比较。
表子查询:结果集为多行多列,用于主查询中嵌套另一个完整的表查询。
from
或 where
中。>
, <
等)搭配使用。in
, any
, all
等)搭配使用。select
语句中的子查询例外。in
与 not in
in
用于匹配子查询结果中的任意一个值。not in
用于匹配不属于子查询结果中的任何值。in
和 not in
可与多个值比较操作符结合使用。any
与 all
any
表示“对于子查询结果中的任意一个值,满足比较操作符即可”。all
表示“对于子查询结果中的所有值,必须满足比较操作符”。any
和 all
通常与比较操作符(如 >
, <
等)结合使用。exists
exists
用于判断子查询是否有结果,返回值为 1
(存在)或 0
(不存在)。exists
的子查询通常不返回具体数据。查询员工的 job_id
与 141 号员工相同,且 salary
比 143 号员工多的员工姓名、job_id
和 salary
。
SELECT name, job_id, salaryFROM employeesWHERE job_id = ( SELECT job_id FROM employees WHERE employee_id = 142 ) AND salary > ( SELECT salary FROM employees WHERE employee_id = 143 );
查询其他工种(除 IT_PROG
外)中某一工资低的员工信息。
SELECT employee_id, name, job_id, salaryFROM employeesWHERE salary < ANY( SELECT distinct salary FROM employees WHERE job_id = 'IT_PROG' ) AND job_id < 'IT_PROG';
查询每个部门的平均工资等级。
SELECT avg_res.avgs, avg_res.department_id, g.grade_levelFROM ( SELECT AVG(salary) avgs, department_id FROM employees GROUP BY department_id) avg_res, job_grades gWHERE avg_res.avgs BETWEEN g.lowest_sal AND g.highest_sal;
exists
子查询查询有员工的部门名。
SELECT department_nameFROM departments dWHERE exists( SELECT * FROM employees e WHERE d.department_id = e.department_id );
通过以上案例可以看出,子查询在 SQL 中的应用非常广泛。无论是用于单值比较、多值比较还是表关联,子查询都能帮助开发者实现复杂的查询需求。
转载地址:http://aebfk.baihongyu.com/