mysql?子查詢的概述和分類及單行子查詢功能實現(xiàn)
子查詢引入
查詢的基本結構已經給大家了,子查詢里面也是有一些新的內容,子查詢其實就是在查詢中嵌套另一個查詢,叫嵌套查詢可能大家更容易理解一點..,類似與FOR循環(huán)和FOR循環(huán)的嵌套,這一章是我們查詢的最難的部分,大家
難度是查詢的頂峰,多表查詢和子查詢是非常重要,SQL優(yōu)化里面主要還是針對查詢的優(yōu)化.
子查詢是mysql4.1里面引入的,現(xiàn)在java用的比較多的是8.0,數(shù)據(jù)庫和java企業(yè)都沒有動力去更新,我們講課的向下兼容的,雖然現(xiàn)在是8.0,但是講的還是會涉及,當我們現(xiàn)在有一個需求,查詢誰的工資比a高,所以我們要先查詢abel的工資,然后再把這個工資放入查詢條件中進行查詢.
首先我們看到了這個需求,誰的工資比abel高,我們如何不用子查詢來進行.
SELECT last_name,salary FROM employees WHERE last_name='abel'

我們可以看到abel工資的11000,我們現(xiàn)在就查詢工資比11000高就行.

我們要和數(shù)據(jù)庫服務器進行2次交互,效率肯定是比較低的,我們就像能不能用一條語句來進行.我們是不是可以用自連接來進行
SELECT T1.last_name,T1.salary FROM employees T1 JOIN employees T2 ON T1.salary>T2.salary AND T2.last_name='abel'

這時我們利用自連接,把所有工資比abel高的字段篩選出來.
方式2自連接肯定要比方式1塊
1雖然這個條件可以用多表查詢,但是其他類似的條件就不能用自連接
2:這個不容易想出來,不夠直觀
那么我們就可以引入子查詢
子查詢介紹
我們先寫WHERE條件,因為這個條件不是一個值,我們需要用另一個查詢才能查詢出來,所以我們直接把查詢條件改成另一個查詢結構SELECT last_name,salary
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE last_name='abel')
注意這里的查詢條件只能出現(xiàn)一個值.由一個問題需求引入一個查詢
首先我們談談一個名稱,一個稱謂,子查詢包括了外查詢,和內查詢.
外面的查詢就叫外查詢,里面的就叫內查詢,這是相對的叫法.

外查詢也被叫做主查詢,內查詢也被叫子查詢.
接下來我們看看有什么具體的要求,
1子查詢是在主查詢之前一次查詢,
2子查詢的結果被外查詢使用
注意事項
1:子查詢要被括號包裹,由于子查詢比較復雜,用括號包裹會比較清晰
2子查詢要放在比較條件的右側
Ps,就是在比較符號的后面,如果在前面就是這樣
SELECT last_name,salary
FROM employees
WHERE (
SELECT salary
FROM employees
WHERE last_name='abel')<salary
我們會發(fā)現(xiàn)這樣也行,但是為什么要這樣呢,我們這是為了可讀性和美觀的考慮.頭短尾長比較好.
3.單行操作費對應單行子查詢,多行操作符對應多行子查詢.
子查詢分類
分類可以從不同的角度去分,第一個角度,
角度1: 出多個結果或者一個結
單行子查詢,,
查詢之后出一個結果的就是單行子查詢
多行子查詢
查詢之后出多個結果的就是單行子查詢
角度2內查詢是否被執(zhí)行多次
相關查詢:
比如我們需要查詢部門工資大于本部門平均工資的員工信息
里面的子查詢會因為外查詢記錄部門的不同返回的值而改變.也就是返回不同的平均值.
比如白和白生的就是黑的,
不相關查詢
比如需求我們要查詢工資大于公司的平均工資的員工.
里面的子查詢,或者說內查詢條件,不會跟隨外查詢記錄的改變而改變,
這里的就說清楚了,因為我們的子查詢語句比較多,所以要寫的行數(shù)也比較多,所以我們先做一個分類,我們下面要講的就是單行子查詢和多行子查詢的案例.
我會把這兩個查詢的范圍都限制在不相關子查詢內容,所以下面的相關子查詢把這個難度就調高起來
趁熱打鐵開始吧
也就是里面只有一個數(shù)據(jù)供我們外部使用,
子查詢的編寫技巧:
1從里往外寫
2從外往里寫
單行子查詢
單行子查詢操作符號
= != > < <> <= >=
也就是我們之前的邏輯操作符號
情況1
”查詢工資大于149號員工工資的員工信息
由于我們不知道149號員工的工資,我們就要進行子查詢.”
這里因為比較簡單,所以我們技巧1和技巧2都可以
我們就先寫子查詢
SELECT employee_id
FROM employees
WHERE employee_id=149
再寫外查詢

沒問題,我們就查詢出來了
題目2返回job_id與141號員工相同,salary比143員工多的員工姓名
SELECT employee_id,job_id,salary
FROM employees
WHERE job_id=(
SELECT job_id
FROM employees
WHERE employee_id=141)
AND salary>(
SELECT salary
FROM employees
WHERE employee_id=143)
如果我們看見了一個查詢語句,我們可以把這個語句轉換為中文嗎,也就是要看出這個查詢語句來看出它的需求.這個能力也要有,我們現(xiàn)在主要是做需求.
題目返回公司工資最少的員工last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
SELECT MIN(salary)
FROM employees)
注意這里可能是好幾個員工,但是還是單行子查詢,因為我們內查詢只返回一條記錄
情況2
查詢與141號員工的manager_id和department_id相同的其他員工的employee_id,manager_id,department_id
我們先不用理過濾條件,查詢其他員工的
employee_id,manager_id,department_id還是會寫的把,我們就先寫外查詢 SELECT employee_id,manager_id,department_id FROM employees WHERE
然后補充內查詢
SELECT employee_id,manager_id,department_id
FROM employees
WHERE manager_id =(
SELECT manager_id
FROM employees
WHERE employee_id=141)
AND department_id =(
SELECT department_id
FROM employees
WHERE employee_id=141)
這是方式1:
方式1成對子查詢
我們還有一個方式2,可以一次性把兩個字段條件寫在一起
SELECT employee_id,manager_id,department_id
FROM employees
WHERE (manager_id,department_id) =(
SELECT manager_id,department_id
FROM employees
WHERE employee_id=141)
結果是一致的,這叫我們的成對子查詢.效率上差別不大,上面的適用性比較高,所以這個不會寫也沒事,了解就可以了.適用場景太窄了
情況3,HAVING中的子查詢
題目:查詢最低工資大于50號部門最低工資的 部門id和其最低工資
SELECT MIN(salary)
SELECT department_id,MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM employees
WHERE department_id=50)
因為五十號部門工資是不確定的,所以我們要用到子查詢
這里不行要空值我們就可以用外查詢WHERE篩選掉
SELECT department_id,MIN(salary)
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM employees
WHERE department_id=50)
所以我們HAVING中我們也可以使用子查詢
情況4:CASE中的子查詢
顯示員工的employee_id,last_name和location.其中若員工department_id與location_id為1800的department_id相同則location為canada,其余為USA
這里我們還是先寫外查詢再寫內查詢,
SELECT employee_id,last_name,(
CASE department_id
WHEN (
SELECT department_id
FROM departments
JOIN locations T3
ON T3.location_id=departments.location_id
WHERE T3.location_id=1800)
THEN
'canada'
ELSE
'USA'
END
) "location"
FROM employees
情況5:子查詢中的空值問題.
如果子查詢的結果是空值,那么不會報錯,返回的會是一個空表比如下面這種情況
SELECT last_name,job_id FROM employees WHERE job_id=(SELECT job_id FROM employees WHERE last_name=102)

情況6:非法使用子查詢
如果我們用單行操作符進行多行操作,會出現(xiàn)什么情況
這時會直接報錯

到此這篇關于mysql 子查詢的概述和分類及單行子查詢的文章就介紹到這了,更多相關mysql 子查詢內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
MySQL升級PostgreSQL遇到的一些常見問題及解決方案
MySQL是一款性能優(yōu)越、數(shù)據(jù)可靠性高的數(shù)據(jù)庫軟件,然而為了保證其長期有效運行,數(shù)據(jù)庫升級是非常重要的,下面這篇文章主要給大家介紹了關于MySQL升級PostgreSQL遇到的一些常見問題及解決方案的相關資料,需要的朋友可以參考下2024-05-05
解決MySQL server has gone away錯誤的方案
在本篇文章里小編給大家分享的是一篇關于MySQL server has gone away錯誤的解決辦法,有需要的朋友們可以參考下。2020-02-02
mysql中secure_file_priv=不生效問題及解決
這篇文章主要介紹了mysql中secure_file_priv=不生效問題及解決方案,以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家,2024-01-01
MySQL從一個表中查出數(shù)據(jù)并插入到另一個表的詳細處理方案
這篇文章主要給大家介紹了關于MySQL從一個表中查出數(shù)據(jù)并插入到另一個表的詳細處理方案,文中通過圖文介紹的非常詳細,對大家學習或者使用MySQL具有一定的參考借鑒價值,需要的朋友可以參考下2023-12-12
Mysql version can not be less than 4.1 出錯解決辦法
這篇文章主要介紹了Mysql version can not be less than 4.1 解決辦法的相關資料,需要的朋友可以參考下2016-10-10

