MySQL 学习笔记(16)— 子查询(单行单列、一行多列、多行多列、 ALL、ANY、SOME 运算符、EXISTS 操作符)
1. 子查詢概念
子查詢是指嵌套在其他語句(SELECT 、 INSERT 、 UPDATE 、 DELETE 等)中的 SELECT 語句;子查詢也稱為內查詢( inner query )或者嵌套查詢( nested query );子查詢必須位于括號之中。
SQL 中的子查詢可以分為以下三種類型:
- 標量子查詢(Scalar Subquery):返回單個值(一行一列)的子查詢。
- 行子查詢(Row Subquery):返回單行結果(一行多列)的子查詢,標量子查詢是行子查詢的一個特例。
- 表子查詢(Table Subquery):返回一個虛擬表(多行多列)的子查詢,行子查詢是表子查詢的一個特例。
2. 標量子查詢
標量子查詢的結果就像一個常量一樣,可以用于 SELECT 、 WHERE 、 GROUP BY 、 HAVING 以及 ORDER BY 等子句中。以下示例在 SELECT 列表中使用標量子查詢計算員工的月薪與平均月薪的差值:
SELECT emp_name, salary,salary - (SELECT AVG(salary) FROM employee) AS salary_diffFROM employeeWHERE emp_id <= 6;
3. 行子查詢
行子查詢可以當作一個一行多列的臨時表使用。以下語句查找所有與“臥虎 ”在同一個部門并且職位相同的員工:
-- Oracle、MySQL 以及 PostgreSQL 實現
SELECT emp_name, dept_id, job_idFROM employeeWHERE (dept_id, job_id) = (SELECT dept_id, job_id FROM employee WHERE emp_name = '臥虎')AND emp_name != '臥虎';
子查詢返回了 “臥虎”所在的部門編號和職位編號,這兩個值構成了一行數據;然后外部查詢的 WHERE 條件使用該數據進行過濾, AND 操作符用于排除“臥虎”自己。
行子查詢的實際使用較少, SQL Server 中不支持行子查詢。
4. 表子查詢
當子查詢返回的結果包含多行數據時,稱為表子查詢。表子查詢通常用于查詢條件或者 FROM 子句中。
對于這種可能返回多行數據的表子查詢,可以使用 IN 和 NOT IN 運算符進行判斷。以上示例可以使用 IN 運算符改寫如下:
SELECT emp_nameFROM employeeWHERE job_id IN (SELECT job_id FROM employee WHERE dept_id = 3);
5. ALL、ANY/SOME 運算符
ALL 運算符與比較運算符(=、!=、<、<=、>、>=)結合表示等于、不等于、小于、小于等于、大于或者大于等于子查詢結果中的所有值。
ANY/SOME 運算符與比較運算符(=、!=、<、<=、>、>=)結合表示等于、不等于、小于、小于等于、大于或者大于等于子查詢結果中的任意值。
SELECT emp_nameFROM employeeWHERE job_id = ANY (SELECT job_id FROM employee WHERE dept_id = 3);
6. EXISTS 操作符
EXISTS 操作符用于判斷子查詢結果的存在性。如果子查詢存在任何結果, EXISTS 返回真;否則,返回假。
以下語句查找存在女性員工的部門:
SELECT d.dept_nameFROM department dWHERE EXISTS ( SELECT 1FROM employee eWHERE e.sex = '女'AND e.dept_id = d.dept_id)ORDER BY dept_name;
EXISTS 之后是一個關聯子查詢,先執行外查詢找到 d.dept_id;然后依次將 d.dept_id 傳遞給子查詢,判斷該部門是否存在女性員工;子查詢一旦找到任何數據立即返回結果。 EXISTS 只判斷結果的存在性,因此子查詢的 SELECT 列表中的內容無所謂,通常使用一個常量值。該查詢的結果表明“研發部”和“財務部”存在女性員工。
EXISTS 只要找到任何數據,立即終止子查詢的執行,因此可以提高查詢的性能。
另外, NOT EXISTS 執行相反的操作。如果想要查找不存在女性員工的部門,可以將上例中的 EXISTS 替換成 NOT EXISTS 。
現在,我們知道 [NOT] EXISTS 和 [NOT] IN 都可以用于判斷子查詢返回的結果。但是它們之間存在一個重要的區別:
[NOT] EXISTS 只檢查存在性, [NOT] IN 需要比較實際的值是否相等。因此,當子查詢的結果包含 NULL 值時, EXISTS 仍然返回結果, NOT EXISTS 不返回結果;但是此時 IN 和 NOT IN 都不會返回結果,因為 ( X = NULL ) 和 NOT (X = NULL) 的結果都是未知。
通常來說, [NOT] EXISTS 的性能比 [NOT] IN 更好,盡量使用 [NOT] EXISTS 。
總結
以上是生活随笔為你收集整理的MySQL 学习笔记(16)— 子查询(单行单列、一行多列、多行多列、 ALL、ANY、SOME 运算符、EXISTS 操作符)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “翦碎红绡却作团”下一句是什么
- 下一篇: 原清则流清的下一句是什么啊?