mysql?子查詢的概述和分類及單行子查詢功能實(shí)現(xiàn)
子查詢引入
查詢的基本結(jié)構(gòu)已經(jīng)給大家了,子查詢里面也是有一些新的內(nèi)容,子查詢其實(shí)就是在查詢中嵌套另一個查詢,叫嵌套查詢可能大家更容易理解一點(diǎ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,但是講的還是會涉及,當(dāng)我們現(xiàn)在有一個需求,查詢誰的工資比a高,所以我們要先查詢abel的工資,然后再把這個工資放入查詢條件中進(jìn)行查詢.
首先我們看到了這個需求,誰的工資比abel高,我們?nèi)绾尾挥米硬樵儊磉M(jìn)行.
SELECT last_name,salary FROM employees WHERE last_name='abel'

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

我們要和數(shù)據(jù)庫服務(wù)器進(jìn)行2次交互,效率肯定是比較低的,我們就像能不能用一條語句來進(jìn)行.我們是不是可以用自連接來進(jìn)行
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條件,因為這個條件不是一個值,我們需要用另一個查詢才能查詢出來,所以我們直接把查詢條件改成另一個查詢結(jié)構(gòu)SELECT last_name,salary
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE last_name='abel')
注意這里的查詢條件只能出現(xiàn)一個值.由一個問題需求引入一個查詢
首先我們談?wù)勔粋€名稱,一個稱謂,子查詢包括了外查詢,和內(nèi)查詢.
外面的查詢就叫外查詢,里面的就叫內(nèi)查詢,這是相對的叫法.

外查詢也被叫做主查詢,內(nèi)查詢也被叫子查詢.
接下來我們看看有什么具體的要求,
1子查詢是在主查詢之前一次查詢,
2子查詢的結(jié)果被外查詢使用
注意事項
1:子查詢要被括號包裹,由于子查詢比較復(fù)雜,用括號包裹會比較清晰
2子查詢要放在比較條件的右側(cè)
Ps,就是在比較符號的后面,如果在前面就是這樣
SELECT last_name,salary
FROM employees
WHERE (
SELECT salary
FROM employees
WHERE last_name='abel')<salary
我們會發(fā)現(xiàn)這樣也行,但是為什么要這樣呢,我們這是為了可讀性和美觀的考慮.頭短尾長比較好.
3.單行操作費(fèi)對應(yīng)單行子查詢,多行操作符對應(yīng)多行子查詢.
子查詢分類
分類可以從不同的角度去分,第一個角度,
角度1: 出多個結(jié)果或者一個結(jié)
單行子查詢,,
查詢之后出一個結(jié)果的就是單行子查詢
多行子查詢
查詢之后出多個結(jié)果的就是單行子查詢
角度2內(nèi)查詢是否被執(zhí)行多次
相關(guān)查詢:
比如我們需要查詢部門工資大于本部門平均工資的員工信息
里面的子查詢會因為外查詢記錄部門的不同返回的值而改變.也就是返回不同的平均值.
比如白和白生的就是黑的,
不相關(guān)查詢
比如需求我們要查詢工資大于公司的平均工資的員工.
里面的子查詢,或者說內(nèi)查詢條件,不會跟隨外查詢記錄的改變而改變,
這里的就說清楚了,因為我們的子查詢語句比較多,所以要寫的行數(shù)也比較多,所以我們先做一個分類,我們下面要講的就是單行子查詢和多行子查詢的案例.
我會把這兩個查詢的范圍都限制在不相關(guān)子查詢內(nèi)容,所以下面的相關(guān)子查詢把這個難度就調(diào)高起來
趁熱打鐵開始吧
也就是里面只有一個數(shù)據(jù)供我們外部使用,
子查詢的編寫技巧:
1從里往外寫
2從外往里寫
單行子查詢
單行子查詢操作符號
= != > < <> <= >=
也就是我們之前的邏輯操作符號
情況1
”查詢工資大于149號員工工資的員工信息
由于我們不知道149號員工的工資,我們就要進(jìn)行子查詢.”
這里因為比較簡單,所以我們技巧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)
如果我們看見了一個查詢語句,我們可以把這個語句轉(zhuǎn)換為中文嗎,也就是要看出這個查詢語句來看出它的需求.這個能力也要有,我們現(xiàn)在主要是做需求.
題目返回公司工資最少的員工last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
SELECT MIN(salary)
FROM employees)
注意這里可能是好幾個員工,但是還是單行子查詢,因為我們內(nèi)查詢只返回一條記錄
情況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
然后補(bǔ)充內(nèi)查詢
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)
結(jié)果是一致的,這叫我們的成對子查詢.效率上差別不大,上面的適用性比較高,所以這個不會寫也沒事,了解就可以了.適用場景太窄了
情況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
這里我們還是先寫外查詢再寫內(nèi)查詢,
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:子查詢中的空值問題.
如果子查詢的結(jié)果是空值,那么不會報錯,返回的會是一個空表比如下面這種情況
SELECT last_name,job_id FROM employees WHERE job_id=(SELECT job_id FROM employees WHERE last_name=102)

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

到此這篇關(guān)于mysql 子查詢的概述和分類及單行子查詢的文章就介紹到這了,更多相關(guān)mysql 子查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL DBA教程:Mysql性能優(yōu)化之緩存參數(shù)優(yōu)化
在平時被問及最多的問題就是關(guān)于 MySQL 數(shù)據(jù)庫性能優(yōu)化方面的問題,所以最近打算寫一個MySQL數(shù)據(jù)庫性能優(yōu)化方面的系列文章,希望對初中級 MySQL DBA 以及其他對 MySQL 性能優(yōu)化感興趣的朋友們有所幫助2014-03-03
Navicat自動備份MySQL數(shù)據(jù)的流程步驟
對于從事IT開發(fā)的工程師,數(shù)據(jù)備份我想大家并不陌生,這件工程太重要了!對于比較重要的數(shù)據(jù),我們希望能定期備份,每天備份1次或多次,或者是每周備份1次或多次,所以本文給大家介紹了Navicat自動備份MySQL數(shù)據(jù)的流程步驟,需要的朋友可以參考下2024-12-12
MySQL性能優(yōu)化之一條SQL在MySQL中執(zhí)行的過程詳解
天天和數(shù)據(jù)庫打交道,一天能寫上幾十條 SQL 語句,但你知道系統(tǒng)是如何和數(shù)據(jù)庫交互的嗎?下面這篇文章主要給大家介紹了關(guān)于MySQL性能優(yōu)化之一條SQL在MySQL中執(zhí)行的過程的相關(guān)資料,需要的朋友可以參考下2023-02-02
如何使用分區(qū)處理MySQL的億級數(shù)據(jù)優(yōu)化
mysql在查詢上千萬級數(shù)據(jù)的時候,通過索引可以解決大部分查詢優(yōu)化問題。但是在處理上億數(shù)據(jù)的時候,應(yīng)該怎么解決,本文就是用分區(qū)來優(yōu)化一下,感興趣的一起來了解一下2021-06-06
MySQL中Order By多字段排序規(guī)則代碼示例
這篇文章主要介紹了MySQL中Order By多字段排序規(guī)則代碼示例,小編覺得挺不錯的,這里給大家分享下,需要的朋友可以參考。2017-10-10

