Sql简介 专题
专题目录
您的位置:database > Sql简介专题 > SQL相关子查询
SQL相关子查询
作者:--    发布时间:2019-11-20

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


网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册