SQL子查询(Subquery)是在一个查询语句中嵌套另一个查询语句的功能。子查询可以出现在SELECT
、FROM
、WHERE
或HAVING
等子句中,用于返回单个值、一行值或一列值,以供外部查询使用。
多层嵌套查询
(也称为多级嵌套查询或深度嵌套查询)是指在一个查询语句中嵌套了多个子查询的情况。这种查询结构允许我们逐步细化查询条件,以便从数据库表中检索出所需的信息。多层嵌套查询通常用于处理复杂的查询需求,特别是当需要基于多个条件或来自不同表的数据进行筛选和计算时。
下面将详细介绍SQL子查询,并通过举例来说明其用法。
子查询的分类
1、标量子查询:返回单个值的子查询。
2、列子查询:返回一列值的子查询。
3、行子查询:返回一行值的子查询。
4、表子查询:返回多行多列值的子查询,结果可以看作是一个临时表。
子查询的使用场景
1、在SELECT子句中使用子查询:作为计算字段的一部分。
2、在FROM子句中使用子查询:将子查询结果作为临时表供外部查询使用。
3、在WHERE子句中使用子查询:作为过滤条件。
4、在HAVING子句中使用子查询:对分组结果进行过滤。
举例
示例1
:标量子查询
假设我们有一个名为employees的表,其中包含员工的薪资信息。我们想要找出薪资最高的员工:
SELECT employee_name, salary
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);
这里,子查询(SELECT MAX(salary) FROM employees
)返回了薪资的最大值,外部查询则根据这个最大值筛选出对应的员工姓名和薪资。
示例2
:列子查询
假设我们有两个表:orders(订单表)和customers(客户表)。我们想要找出所有下过订单的客户姓名:
SELECT customer_name
FROM customers
WHERE customer_id IN (SELECT DISTINCT customer_id FROM orders);
这里,子查询(SELECT DISTINCT customer_id FROM orders
)返回了所有下过订单的客户ID,外部查询则根据这些ID筛选出对应的客户姓名。
示例3
:行子查询
假设我们想要找出薪资和某个特定员工(例如员工ID为1001)相同的所有员工:
SELECT employee_name, salary
FROM employees
WHERE (salary, employee_id) IN (SELECT salary, employee_id FROM employees WHERE employee_id = 1001);
这里,子查询返回了员工ID为1001的员工的薪资和ID,外部查询则根据这个薪资和ID筛选出所有薪资相同的员工。
示例4
:表子查询
假设我们想要找出每个部门的员工数:
SELECT department_id, COUNT(*) as employee_count
FROM (SELECT employee_id, department_id FROM employees) as emp_dept
GROUP BY department_id
这里,子查询返回了所有员工的ID和所在部门ID,然后外部查询对这个结果集进行分组和计数,得到每个部门的员工数。
在类似以上的嵌套查询中,子查询的结果往往是一个集合,所以IN是最常用的谓词。
除此之外,在嵌套查询中经常还会使用一些运算符以及ANY、ALL、EXISTS谓词,下面是它们的含义:
比较运算符:用于比较两个值的大小或相等性。
当子查询返回的是单值时,父查询和子查询之间可以使用这些比较运算符进行值的比较。
=
:等于
>
:大于
<
:小于
>=
:大于等于
<=
:小于等于
<>
: 或
!=
:不等于
逻辑运算符:用于组合多个条件。
AND
:且(两个条件都满足)
OR
:或(至少一个条件满足)
NOT
:非(条件不满足)
BETWEEN 运算符
用于在某个范围内筛选值,通常与两个值一起使用。虽然它不是一个谓词,但在多层嵌套查询中也可能会用到。
示例
:
SELECT column_name
FROM table_name
WHERE column_value BETWEEN value1 AND value2;
ANY 谓词
ANY 谓词与子查询结合使用时,表示主查询中的值与子查询结果集中的任意一个值进行比较。
示例
:
SELECT column_name
FROM table_name
WHERE column_value > ANY (SELECT column_value FROM another_table);
大于 ANY (>)
如果主查询中的值大于子查询结果集中的任意一个值,则返回TRUE。
小于 ANY (<)
如果主查询中的值小于子查询结果集中的任意一个值,则返回TRUE。
大于等于 ANY (>=)
如果主查询中的值大于或等于子查询结果集中的任意一个值,则返回TRUE。
小于等于 ANY (<=)
如果主查询中的值小于或等于子查询结果集中的任意一个值,则返回TRUE。
等于 ANY (=)
如果主查询中的值等于子查询结果集中的任意一个值,则返回TRUE。
不等于 ANY (!= 或 <>)
如果主查询中的值不等于子查询结果集中的任意一个值,则返回TRUE。
ALL 谓词
ALL 谓词与子查询结合使用时,表示主查询中的值与子查询结果集中的所有值进行比较。
示例
:
SELECT column_name
FROM table_name
WHERE column_value > ALL (SELECT column_value FROM another_table);
大于 ALL (>)
如果主查询中的值大于子查询结果集中的所有值,则返回TRUE。
小于 ALL (<)
如果主查询中的值小于子查询结果集中的所有值,则返回TRUE。
大于等于 ALL (>=)
如果主查询中的值大于或等于子查询结果集中的所有值,则返回TRUE。
小于等于 ALL (<=)
如果主查询中的值小于或等于子查询结果集中的所有值,则返回TRUE。
等于 ALL (=)
如果主查询中的值等于子查询结果集中的所有值(通常这种情况很少见,因为子查询返回多个值时,很难有一个值等于所有值),则返回TRUE。但在实际应用中,这种情况可能并不实用。
不等于 ALL (!= 或 <>)
如果主查询中的值不等于子查询结果集中的所有值,则返回TRUE。
EXISTS 谓词
用于检查子查询是否返回任何结果。与 IN 不同,EXISTS 只关心子查询是否返回了至少一行数据,而不关心具体返回了什么数据。
示例
:
SELECT column_name
FROM table_name t1
WHERE EXISTS (SELECT 1 FROM another_table t2 WHERE t1.id = t2.id)
原创 武旭鹏 米宏Office