在本教程中,您将了解SQL相关子查询,它是使用外部查询中的值的子查询。
1. SQL相关子查询简介
下面通过一个例子开始。
请参阅示例数据库中的employees
表:
desc employees;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| employee_id | int(11) | NO | PRI | NULL | auto_increment |
| first_name | varchar(20) | YES | | NULL | |
| last_name | varchar(25) | NO | | NULL | |
| email | varchar(100) | NO | | NULL | |
| phone_number | varchar(20) | YES | | NULL | |
| hire_date | date | NO | | NULL | |
| job_id | int(11) | NO | MUL | NULL | |
| salary | decimal(8,2) | NO | | NULL | |
| manager_id | int(11) | YES | MUL | NULL | |
| department_id | int(11) | YES | MUL | NULL | |
+---------------+--------------+------+-----+---------+----------------+
10 rows in set
以下查询查找薪水大于所有员工平均薪水的员工:
SELECT
employee_id,
first_name,
last_name,
salary
FROM
employees
WHERE
salary > (SELECT
AVG(salary)
FROM
employees);
执行上面查询语句,得到以下结果:
+-------------+------------+-----------+--------+
| employee_id | first_name | last_name | salary |
+-------------+------------+-----------+--------+
| 100 | Steven | Lee | 24000 |
| 101 | Neena | Wong | 17000 |
| 102 | Lex | Liang | 17000 |
| 103 | Alexander | Lee | 9000 |
| 108 | Nancy | Chen | 12000 |
| 109 | Daniel | Chen | 9000 |
| 110 | John | Chen | 8200 |
| 114 | Avg | Su | 11000 |
| 121 | Max | Han | 8200 |
| 145 | John | Liu | 14000 |
| 146 | Karen | Liu | 13500 |
| 176 | Jonathon | Yang | 8600 |
| 177 | Jack | Yang | 8400 |
| 201 | Michael | Zhou | 13000 |
| 204 | Hermann | Wu | 10000 |
| 205 | Shelley | Wu | 12000 |
| 206 | William | Wu | 8300 |
+-------------+------------+-----------+--------+
17 rows in set
在此示例中,子查询在WHERE
子句中使用。可以从此查询中看到一些要点:
首先,可以执行子查询,此子查询独立返回所有员工的平均工资。
SELECT
AVG(salary)
FROM
employees;
其次,数据库系统只需要对子查询进行一次评估。
第三,外部查询使用从子查询返回的结果。 外部查询依赖于子查询的值。 但是,子查询不依赖于外部查询。 有时,我们称这个子查询是一个普通的子查询。
与普通子查询不同,相关子查询是使用外部查询中的值的子查询。 此外,可以针对外部查询选择的每一行评估相关子查询一次。 因此,使用相关子查询的查询可能很慢。
相关子查询也称为重复子查询或同步子查询。
2. SQL相关的子查询示例
让我们看一下相关子查询的一些例子,以便更好地理解它们。
2.1. WHERE子句示例中的SQL相关子查询
以下查询查找薪水高于其部门员工平均薪水的所有员工:
SELECT
employee_id,first_name,last_name,salary,department_id
FROM
employees e
WHERE
salary > (SELECT
AVG(salary)
FROM
employees
WHERE
department_id = e.department_id)
ORDER BY
department_id , first_name , last_name;
执行上面查询语句,得到以下结果:
在此示例中,外部查询是:
SELECT
employee_id,
first_name,
last_name,
salary,
department_id
FROM
employees e
WHERE
salary >
...
相关子查询是:
SELECT
AVG( list_price )
FROM
products
WHERE
category_id = p.category_id
对于每个员工,数据库系统必须执行一次相关子查询,以计算当前员工部门中员工的平均工资。
2.2. SELECT子句示例中的SQL相关子查询
以下查询返回员工及其部门中所有员工的平均薪水:
SELECT
employee_id,
first_name,
last_name,
department_name,
salary,
(SELECT
ROUND(AVG(salary),0)
FROM
employees
WHERE
department_id = e.department_id) avg_salary_in_department
FROM
employees e
INNER JOIN
departments d ON d.department_id = e.department_id
ORDER BY
department_name,
first_name,
last_name;
执行上面查询语句,得到以下结果:
+-------------+------------+-----------+-----------------+--------+--------------------------+
| employee_id | first_name | last_name | department_name | salary | avg_salary_in_department |
+-------------+------------+-----------+-----------------+--------+--------------------------+
| 103 | Alexander | Lee | IT | 9000 | 5760 |
| 104 | Bruce | Wong | IT | 6000 | 5760 |
| 105 | David | Liang | IT | 4800 | 5760 |
| 107 | Diana | Chen | IT | 4200 | 5760 |
| 106 | Valli | Chen | IT | 4800 | 5760 |
| 203 | Susan | Zhou | 人力资源 | 6500 | 6500 |
| 205 | Shelley | Wu | 会计 | 12000 | 10150 |
... ...
| 119 | Karen | Zhang | 采购 | 2500 | 4150 |
| 116 | Shelli | Zhang | 采购 | 2900 | 4150 |
| 117 | Sigal | Zhang | 采购 | 2800 | 4150 |
| 179 | Charles | Yang | 销售 | 6200 | 9617 |
| 177 | Jack | Yang | 销售 | 8400 | 9617 |
| 145 | John | Liu | 销售 | 14000 | 9617 |
| 176 | Jonathon | Yang | 销售 | 8600 | 9617 |
| 146 | Karen | Liu | 销售 | 13500 | 9617 |
| 178 | Kimberely | Yang | 销售 | 7000 | 9617 |
+-------------+------------+-----------+-----------------+--------+--------------------------+
40 rows in set
对于每个员工,数据库系统必须执行一次相关子查询,以计算员工部门的平均工资。
2.3. SQL将子查询与EXISTS运算符示例相关联
经常使用与EXISTS
运算符相关的子查询。 例如,以下查询返回没有依赖项的所有员工:
SELECT
employee_id, first_name, last_name
FROM
employees e
WHERE
NOT EXISTS( SELECT
*
FROM
dependents d
WHERE
d.employee_id = e.employee_id)
ORDER BY first_name , last_name;
执行上面查询语句,得到以下结果:
在本教程中,您了解了SQL相关子查询以及如何将其应用于形成复杂查询。
上一篇:
SQL子查询
下一篇:
SQL Exists运算符