在本教程中,您将了解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.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相关子查询以及如何将其应用于形成复杂查询。