嵌套套娃,MySQL子查询,单行与多行子查询,相关和不相关(关联)子查询,完整详细可收藏
文章目錄
- 1、需求分析與問題解決
- 2、單行子查詢
- 3、多行子查詢
- 4、相關子查詢
- 5、拋一個思考題
子查詢指一個查詢語句嵌套在另一個查詢語句內部的查詢,這個特性從MySQL 4.1開始引入。SQL 中子查詢的使用大大增強了 SELECT 查詢的能力,因為很多時候查詢需要從結果集中獲取數據,或者需要從同一個表中先計算得出一個數據結果,然后與這個數據結果(可能是某個標量,也可能是某個集合)進行比較。
1、需求分析與問題解決
1.1 實際問題
1.2 子查詢的基本使用
子查詢的基本語法結構:
子查詢(內查詢)在主查詢之前一次執行完成。
子查詢的結果被主查詢(外查詢)使用 。
注意事項:
①子查詢要包含在括號內。
②將子查詢放在比較條件的右側。
③單行操作符對應單行子查詢,多行操作符對應多行子查詢。
1.3 子查詢的分類
分類方式1:按內查詢的結果返回一條還是多條記錄,將子查詢分為單行子查詢 、 多行子查詢 。
分類方式2:按內查詢是否被執行多次,將子查詢劃分為相關(或關聯)子查詢和不相關(或非關聯)子查詢 。
子查詢從數據表中查詢了數據結果,如果這個數據結果只執行一次,然后這個數據結果作為主查詢的條件進行執行,那么這樣的子查詢叫做不相關子查詢。
同樣,如果子查詢需要執行多次,即采用循環的方式,先從外部查詢開始,每次都傳入子查詢進行查詢,然后再將結果反饋給外部,這種嵌套的執行方式就稱為相關子查詢。
2、單行子查詢
2.1 單行比較操作符
2.2 代碼示例
2.3 HAVING 中的子查詢
首先執行子查詢,再向主查詢中的HAVING 子句返回結果。
2.4 CASE中的子查詢
在CASE表達式中使用單列子查詢:
3、多行子查詢
①也稱為集合比較子查詢
②內查詢返回多行
③使用多行比較操作符
3.1 多行比較操作符
3.2 代碼示例
返回其它job_id中比job_id為‘IT_PROG’部門任一工資低的員工的員工號、姓名、job_id 以及salary。
返回其它job_id中比job_id為‘IT_PROG’部門所有工資都低的員工的員工號、姓名、job_id以及salary。
4、相關子查詢
4.1 相關子查詢執行流程
如果子查詢的執行依賴于外部查詢,通常情況下都是因為子查詢中的表用到了外部的表,并進行了條件關聯,因此每執行一次外部查詢,子查詢都要重新計算一次,這樣的子查詢就稱之為 關聯子查詢 。相關子查詢按照一行接一行的順序執行,主查詢的每一行都執行一次子查詢。
4.2 代碼示例
題目:查詢員工中工資大于本部門平均工資的員工的last_name,salary和其department_id
方式一:相關子查詢
方式二:在 FROM 中使用子查詢
SELECT last_name,salary,e1.department_id FROM employees e1,(SELECT department_id,AVG(salary) dept_avg_sal FROM employees GROUP BY department_id) e2 WHERE e1.`department_id` = e2.department_id AND e2.dept_avg_sal < e1.`salary`;from型的子查詢:子查詢是作為from的一部分,子查詢要用()引起來,并且要給這個子查詢取別名, 把它當成一張“臨時的虛擬的表”來使用。
在ORDER BY 中使用子查詢:
#查詢員工的id,salary,按照department_name 排序 SELECT employee_id,salary FROM employees e ORDER BY (SELECT department_nameFROM departments dWHERE e.`department_id` = d.`department_id`);4.3 EXISTS 與 NOT EXISTS關鍵字
關聯子查詢通常也會和 EXISTS操作符一起來使用,用來檢查在子查詢中是否存在滿足條件的行。
如果在子查詢中不存在滿足條件的行:
條件返回 FALSE,繼續在子查詢中查找。
如果在子查詢中存在滿足條件的行:
不在子查詢中繼續查找,條件返回 TRUE。
NOT EXISTS關鍵字表示如果不存在某種條件,則返回TRUE,否則返回FALSE。
題目:查詢公司管理者的employee_id,last_name,job_id,department_id信息
#方式一 SELECT employee_id, last_name, job_id, department_id FROM employees e1 WHERE EXISTS ( SELECT *FROM employees e2WHERE e2.manager_id =e1.employee_id);#方式二:自連接 SELECT DISTINCT e1.employee_id, e1.last_name, e1.job_id, e1.department_id FROM employees e1 JOIN employees e2 WHERE e1.employee_id = e2.manager_id;#方式三 SELECT employee_id,last_name,job_id,department_id FROM employees WHERE employee_id IN (SELECT DISTINCT manager_idFROM employees);4.4 相關更新
UPDATE table1 alias1 SET column = (SELECT expressionFROM table2 alias2WHERE alias1.column = alias2.column);使用相關子查詢依據一個表中的數據更新另一個表的數據。
4.4 相關刪除
DELETE FROM table1 alias1 WHERE column operator (SELECT expressionFROM table2 alias2WHERE alias1.column = alias2.column);使用相關子查詢依據一個表中的數據刪除另一個表的數據。
5、拋一個思考題
誰的工資比Abel的高?
#方式1:自連接 SELECT e2.last_name,e2.salary FROM employees e1,employees e2 WHERE e1.last_name = 'Abel' AND e1.`salary` < e2.`salary`#方式2:子查詢 SELECT last_name,salary FROM employees WHERE salary > (SELECT salaryFROM employeesWHERE last_name = 'Abel');以上兩種方式有好壞之分嗎?
自連接方式好!
題目中可以使用子查詢,也可以使用自連接。一般情況建議使用自連接,因為在許多 DBMS 的處理過程中,對于自連接的處理速度要比子查詢快得多。可以這樣理解:子查詢實際上是通過未知表進行查詢后的條件判斷,而自連接是通過已知的自身數據表進行條件判斷,因此在大部分 DBMS 中都對自連接處理進行了優化。
總結
以上是生活随笔為你收集整理的嵌套套娃,MySQL子查询,单行与多行子查询,相关和不相关(关联)子查询,完整详细可收藏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 选个好网名94个
- 下一篇: 删库跑路?不可回滚?MySQL创建和管理