Mysql數(shù)據(jù)庫中的子查詢、標(biāo)量子查詢、行子查詢、列子查詢及表子查詢實(shí)例代碼
一、什么是子查詢?
子查詢(Subquery)是指嵌套在另一條 SQL 語句中的 SELECT 語句,也叫內(nèi)層查詢。外層包含它的語句叫主查詢或外層查詢。根據(jù)子查詢返回結(jié)果的"形狀",可以分為四種類型:

子查詢 = 一條 SELECT 嵌套在另一條 SELECT 內(nèi)部
- 外面的查詢叫 主查詢 / 外層查詢
- 里面嵌套的查詢叫 子查詢 / 內(nèi)層查詢
執(zhí)行順序:先執(zhí)行子查詢 → 得到結(jié)果 → 再把結(jié)果交給主查詢使用
基本結(jié)構(gòu):
SELECT 字段列表
FROM 表名
WHERE 字段 運(yùn)算符 (
SELECT 字段
FROM 表名
WHERE 條件
);二、子查詢按結(jié)果集分類(最重要)
子查詢一共分 4 類,你必須全部掌握:
1. 標(biāo)量子查詢(單行單列)
標(biāo)量子查詢:
子查詢返回的結(jié)果是一個(gè)單個(gè)值(數(shù)字,字符串,日期等),最簡(jiǎn)單的形式,這種子查詢稱為 標(biāo)量子查詢。
返回:一個(gè)值能用符號(hào):= > < >= <= !=
示例:查詢 “研發(fā)部” 的所有員工
SELECT emp.*
FROM emp
WHERE emp.dept_id = (
SELECT dept.id
FROM dept
WHERE dept.name = '研發(fā)部'
);擴(kuò)展:
ANY:滿足任意一個(gè)ALL:滿足全部
返回單個(gè)值(1行1列),可以用在任何需要單值的地方,比如 =、>、< 等比較運(yùn)算符后面。
示例:查詢工資高于平均工資的員工
SELECT name, salary
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);內(nèi)層的 SELECT AVG(salary) 只返回一個(gè)數(shù)字,外層用 > 直接比較。如果子查詢返回多行,MySQL 會(huì)報(bào)錯(cuò)。
2.列子查詢(Column Subquery)
返回多行一列,常配合 IN、NOT IN、ANY、ALL 使用。
示例 1:IN — 查詢屬于某些部門的員工
SELECT name
FROM employees
WHERE dept_id IN (
SELECT id
FROM departments
WHERE location = '上海'
);示例 2:ANY — 工資比研發(fā)部任意一人高即可
SELECT name
FROM employees
WHERE salary > ANY (
SELECT salary FROM employees WHERE dept_id = 3
);示例 3:ALL — 工資比研發(fā)部所有人都高
SELECT name
FROM employees
WHERE salary > ALL (
SELECT salary FROM employees WHERE dept_id = 3
);ANY 相當(dāng)于"至少一個(gè)滿足",ALL 相當(dāng)于"全部都滿足"。
-- 查詢銷售部和市場(chǎng)部的所有員工的信息 select id from dept where name='銷售部' or name='市場(chǎng)部'; -- 返回值(2,4) select * from emp33 where id in(2,4) 等價(jià)于 select* from emp33 where id in (select id from dept where name='銷售部' or name='市場(chǎng)部');
3. 行子查詢(單行多列)
返回:一行多個(gè)字段示例:查詢和 “張三” 同部門、同職位的員工
SELECT emp.*
FROM emp
WHERE (emp.dept_id, emp.job) = (
SELECT emp.dept_id, emp.job
FROM emp
WHERE emp.name = '張三'
);返回一行多列,需要用行構(gòu)造器 (col1, col2, ...) 來匹配。
示例:查詢與某員工薪資和職位都相同的其他員工
SELECT name
FROM employees
WHERE (salary, job_id) = (
SELECT salary, job_id
FROM employees
WHERE name = '張三'
);括號(hào)里的 (salary, job_id) 和子查詢返回的 (salary, job_id) 一一對(duì)應(yīng)進(jìn)行比較。支持的操作符有 =、<>、<、> 等。
select * from emp33 where (salary,managerid) =(select salary,managerid from emp33 where name='張無忌');
等價(jià)于
select * from emp33 where managerid=(select managerid from emp33 where name='張無忌') and salary=(select salary from emp33 where name='張無忌');
4. 表子查詢(多行多列)
子查詢放在 FROM 后面,當(dāng)作一張臨時(shí)表使用,必須起別名。
示例:查詢每個(gè)部門的平均薪資
sql
SELECT temp.dept_id, temp.avg_sal
FROM (
SELECT emp.dept_id, AVG(emp.salary) AS avg_sal
FROM emp
GROUP BY emp.dept_id
) AS temp;三、子查詢出現(xiàn)的 3 個(gè)位置(高頻考點(diǎn))
子查詢不只能出現(xiàn)在 WHERE 里,還可以出現(xiàn)在不同的位置:
| 位置 | 常見類型 | 說明 |
|---|---|---|
WHERE / HAVING | 標(biāo)量、行、列 | 作為條件值 |
FROM | 表子查詢 | 作為派生表,必須起別名 |
SELECT 后 | 標(biāo)量 | 作為查詢字段值(關(guān)聯(lián)子查詢) |
1. 放在 WHERE 后(最常用,標(biāo)量、行、列)
SELECT emp.name
FROM emp
WHERE emp.dept_id = (
SELECT dept.id
FROM dept
WHERE dept.name = '財(cái)務(wù)部'
);2. 放在 FROM 后(當(dāng)作表,表子查詢)
SELECT temp.name
FROM (
SELECT emp.name
FROM emp
WHERE emp.salary > 10000
) AS temp;3. 放在 SELECT 后(相關(guān)子查詢,標(biāo)量)
SELECT
emp.name,
(
SELECT dept.name
FROM dept
WHERE dept.id = emp.dept_id
) AS dept_name
FROM emp;四、子查詢關(guān)鍵字詳解(IN / ANY / ALL / EXISTS)
1. IN
子查詢返回多個(gè)值時(shí)用
SELECT emp.*
FROM emp
WHERE emp.dept_id IN (
SELECT dept.id
FROM dept
);2. ANY
滿足子查詢?nèi)我庖粋€(gè)條件即可
SELECT emp.*
FROM emp
WHERE emp.salary > ANY (
SELECT emp.salary
FROM emp
WHERE emp.dept_id = 1
);3. ALL
必須滿足子查詢所有條件
SELECT emp.*
FROM emp
WHERE emp.salary > ALL (
SELECT emp.salary
FROM emp
WHERE emp.dept_id = 2
);4. EXISTS
判斷子查詢是否有結(jié)果,有則為真
SELECT emp.*
FROM emp
WHERE EXISTS (
SELECT *
FROM dept
WHERE dept.id = emp.dept_id
);五、子查詢 VS 多表連接(對(duì)比)
- 子查詢:邏輯清晰,適合分步查詢
- 多表連接:效率更高,適合大數(shù)據(jù)量
示例(效果一樣):
-- 子查詢寫法
SELECT emp.name
FROM emp
WHERE emp.dept_id = (
SELECT dept.id
FROM dept
WHERE dept.name = '研發(fā)部'
);
-- 多表連接寫法
SELECT emp.name
FROM emp
INNER JOIN dept
ON emp.dept_id = dept.id
WHERE dept.name = '研發(fā)部';六、子查詢必須遵守的規(guī)則(考試必背)
- 子查詢必須放在 括號(hào)內(nèi)
- 標(biāo)量子查詢只能返回 一個(gè)值
- 列子查詢返回 一列
- FROM 后的子查詢 必須起別名
- 子查詢先執(zhí)行,主查詢后執(zhí)行
- 子查詢中不能使用 order by(除非搭配 limit)
七、綜合實(shí)戰(zhàn)案例(最經(jīng)典)
案例 1:查詢工資最高的員工
SELECT emp.*
FROM emp
WHERE emp.salary = (
SELECT MAX(emp.salary)
FROM emp
);案例 2:查詢每個(gè)部門工資最高的員工
SELECT emp.*
FROM emp
INNER JOIN (
SELECT emp.dept_id, MAX(emp.salary) AS max_sal
FROM emp
GROUP BY emp.dept_id
) AS temp
ON emp.dept_id = temp.dept_id
AND emp.salary = temp.max_sal;案例 3:查詢沒有員工的部門
SELECT dept.*
FROM dept
WHERE dept.id NOT IN (
SELECT DISTINCT emp.dept_id
FROM emp
WHERE emp.dept_id IS NOT NULL
);
理解子查詢的關(guān)鍵在于:先看內(nèi)層查詢返回什么形狀的數(shù)據(jù),再根據(jù)形狀選擇合適的操作符和位置
總結(jié)
到此這篇關(guān)于Mysql數(shù)據(jù)庫中子查詢、標(biāo)量子查詢、行子查詢、列子查詢及表子查詢的文章就介紹到這了,更多相關(guān)Mysql子查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL json相關(guān)函數(shù)及功能詳解
MySQL提供了一系列的JSON函數(shù),用于解析、提取、修改和操作JSON數(shù)據(jù),以下是一些常用的JSON函數(shù)及其功能,需要的朋友可以參考下2023-11-11
MySQL 實(shí)現(xiàn)數(shù)據(jù)分片進(jìn)行數(shù)據(jù)查詢的方案
本文介紹MySQL數(shù)據(jù)分片技術(shù),包括垂直分片和水平分片,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-08-08
數(shù)據(jù)庫索引知識(shí)點(diǎn)整理
這篇文章主要介紹了數(shù)據(jù)庫索引知識(shí)點(diǎn)整理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考2021-01-01
MySQL中存儲(chǔ)過程(procedure)的使用及說明
存儲(chǔ)過程是預(yù)先定義的SQL語句集合,可在數(shù)據(jù)庫中重復(fù)調(diào)用,它們提供事務(wù)性、高效性和安全性,MySQL和Java中均可創(chuàng)建和調(diào)用存儲(chǔ)過程,示例展示了如何在MySQL中創(chuàng)建和調(diào)用存儲(chǔ)過程,以及如何在Java中實(shí)現(xiàn)存儲(chǔ)過程的調(diào)用2025-11-11
MySQL中的驅(qū)動(dòng)表與被驅(qū)動(dòng)表及含義
使用join連接查詢時(shí)如果有where條件,則MySQL執(zhí)行器會(huì)根據(jù)查詢條件過濾后的結(jié)果自動(dòng)選擇驅(qū)動(dòng)表或被驅(qū)動(dòng)表,這篇文章主要介紹了MySQL的驅(qū)動(dòng)表與被驅(qū)動(dòng)表,需要的朋友可以參考下2023-10-10
MySQL多實(shí)例管理如何在一臺(tái)主機(jī)上運(yùn)行多個(gè)mysql
文章詳解了在Linux主機(jī)上通過二進(jìn)制方式安裝MySQL多實(shí)例的步驟,涵蓋端口配置、數(shù)據(jù)目錄準(zhǔn)備、初始化與啟動(dòng)流程,以及排錯(cuò)方法,適用于構(gòu)建讀寫分離架構(gòu),感興趣的朋友一起看看吧2025-07-07

