SQL嵌套查询
结构化查询语言 (SQL) 是一种编程语言。SQL 用于管理存储在关系数据库中的数据。SQL 具有嵌套查询的能力。嵌套查询是在另一个查询内的查询。嵌套查询允许更复杂和更具体的數據检索。在本文中,我们将讨论 SQL 中的嵌套查询、它们的语法和示例。
嵌套查询
在 SQL 中,嵌套查询是指将一个查询放在另一个查询中的查询。内部查询的输出由外部查询使用。嵌套查询有两个 SELECT 语句:一个用于内部查询,另一个用于外部查询。
嵌套查询的语法
嵌套查询的基本语法包括将一个查询放在另一个查询内。内部查询或子查询首先执行,并返回一组随后由外部查询使用的值。嵌套查询的语法如下:
SELECT column1, column2, ... FROM table1 WHERE column1 IN ( SELECT column1 FROM table2 WHERE condition );
SQL 中嵌套查询的类型
子查询可以是关联的或非关联的。
非关联(或独立)嵌套查询
非关联(或独立)嵌套查询:非关联(或独立)子查询独立于外部查询执行。它们的结果将传递给外部查询。
关联嵌套查询
关联子查询为外部查询的每一行执行一次。它们使用外部查询中的值来返回结果。
独立嵌套查询的执行顺序
在独立嵌套查询中,执行顺序是从最内层查询到最外层查询。在内部查询完成执行之前,不会执行外部查询。外部查询使用内部查询的结果。
独立嵌套查询中使用的运算符
IN 运算符
此运算符检查外部查询结果中的列值是否出现在内部查询的结果中。最终结果将包含满足 IN 条件的行。
NOT IN 运算符
此运算符检查外部查询结果中的列值是否未出现在内部查询的结果中。最终结果将包含满足 NOT IN 条件的行。
ALL 运算符
此运算符将外部查询结果的值与内部查询结果的所有值进行比较,如果匹配所有值,则返回该行。
ANY 运算符
此运算符将外部查询结果的值与所有内部查询结果值进行比较,如果与任何值匹配,则返回该行。
关联嵌套查询的执行顺序
在关联嵌套查询中,内部查询使用来自外部查询的值,并且执行顺序与独立嵌套查询不同。
首先,外部查询选择第一行。
内部查询使用所选行的值。它执行其查询并返回结果集。
外部查询使用内部查询返回的结果集。它确定是否应将所选行包含在最终输出中。
步骤 2 和 3 对外部查询结果集中的每一行重复。
此过程可能需要大量资源。如果查询未正确优化,则可能导致性能问题。
关联嵌套查询中使用的运算符
在关联嵌套查询中,可以使用以下运算符:
EXISTS 运算符
此运算符检查子查询是否返回任何行。如果返回至少一行,EXISTS 运算符返回 true,并且外部查询继续执行。如果子查询不返回任何行,则 EXISTS 运算符返回 false,并且外部查询停止执行。
NOT EXISTS 运算符
此运算符检查子查询是否不返回任何行。如果子查询不返回任何行,则 NOT EXISTS 运算符返回 true,并且外部查询继续执行。如果子查询返回至少一行,则 NOT EXISTS 运算符返回 false,并且外部查询停止执行。
ANY 运算符
此运算符将外部查询结果的值与内部查询返回的一个或多个值进行比较。如果与内部查询返回的任何一个值进行比较为真,则该行将包含在最终结果中。
ALL 运算符
此运算符将外部查询结果的值与内部查询返回的所有值进行比较。只有当与内部查询返回的所有值进行比较为真时,该行才会包含在最终结果中。
这些运算符用于创建依赖于外部查询的值才能执行的关联嵌套查询。
示例
考虑以下示例表,以便对这些表执行嵌套查询。
表:employees 表
emp_id |
emp_name |
dept_id |
---|---|---|
1 |
John |
1 |
2 |
Mary |
2 |
3 |
Bob |
1 |
4 |
Alice |
3 |
5 |
Tom |
1 |
表:departments 表
dept_id |
dept_name |
---|---|
1 |
销售部 |
2 |
市场部 |
3 |
财务部 |
表:sales 表
sale_id |
emp_id |
sale_amt |
---|---|---|
1 |
1 |
1000 |
2 |
2 |
2000 |
3 |
3 |
3000 |
4 |
1 |
4000 |
5 |
5 |
5000 |
6 |
3 |
6000 |
7 |
2 |
7000 |
示例 1:查找销售部门中所有员工的姓名。
所需查询
SELECT emp_name FROM employees WHERE dept_id IN (SELECT dept_id FROM departments WHERE dept_name = 'Sales');
输出
emp_name |
---|
John |
Bob |
Tom |
示例 2:查找所有进行过销售的员工的姓名
所需查询
SELECT emp_name FROM employees WHERE EXISTS (SELECT emp_id FROM sales WHERE employees.emp_id = sales.emp_id);
输出
emp_name |
---|
John |
Mary |
Bob |
Alice |
Tom |
此查询从“employees”表中选择所有员工,条件是在“sales”表中存在该员工的销售记录。
示例 3:查找所有销售额大于$1000 的员工的姓名。
所需查询
SELECT emp_name FROM employees WHERE emp_id = ALL (SELECT emp_id FROM sales WHERE sale_amt > 1000);
输出
emp_name |
---|
John |
Mary |
Bob |
Alice |
Tom |
此查询从“employees”表中选择所有员工。条件是他们的 emp_id 等于“sales”表中销售额大于$1000 的所有 emp_id。由于所有员工的销售额都大于$1000,因此返回所有员工姓名。