在本教學中,您將了解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相關子查詢以及如何將其應用於形成複雜查詢。