MySQL中的復(fù)合查詢使用解讀
在實(shí)際開發(fā)中,僅用單表查詢顯然無法滿足復(fù)雜業(yè)務(wù)需求。今天我們就以經(jīng)典的員工管理系統(tǒng)(EMP員工表、DEPT部門表、SALGRADE工資級(jí)別表)為例,聊聊 MySQL 復(fù)合查詢的核心玩法 —— 從單表查詢到多表聯(lián)查、子查詢,再到合并查詢,每一步都附上真實(shí)查詢結(jié)果,幫你直觀理解。
一、先回顧:?jiǎn)伪聿樵兊幕A(chǔ)操作(以EMP表為例)
先明確EMP表基礎(chǔ)數(shù)據(jù)(對(duì)應(yīng)圖片中表內(nèi)容):
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
|---|---|---|---|---|---|---|---|
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600 | 300 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250 | 500 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250 | 1400 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500 | 0 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300 | NULL | 10 |
1. 帶條件的篩選
SELECT * FROM EMP WHERE (sal>500 OR job='MANAGER') AND ename LIKE 'J%';
查詢結(jié)果:
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
|---|---|---|---|---|---|---|---|
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950 | NULL | 30 |
2. 排序與計(jì)算字段
(1)按部門號(hào)升序、工資降序排列
SELECT * FROM EMP ORDER BY deptno, sal DESC;
查詢結(jié)果(節(jié)選核心字段):
| empno | ename | sal | deptno |
|---|---|---|---|
| 7839 | KING | 5000 | 10 |
| 7782 | CLARK | 2450 | 10 |
| 7934 | MILLER | 1300 | 10 |
| 7788 | SCOTT | 3000 | 20 |
| 7902 | FORD | 3000 | 20 |
| 7566 | JONES | 2975 | 20 |
| 7876 | ADAMS | 1100 | 20 |
| 7369 | SMITH | 800 | 20 |
| 7698 | BLAKE | 2850 | 30 |
| 7499 | ALLEN | 1600 | 30 |
| 7844 | TURNER | 1500 | 30 |
| 7521 | WARD | 1250 | 30 |
| 7654 | MARTIN | 1250 | 30 |
| 7900 | JAMES | 950 | 30 |
(2)計(jì)算年薪(工資 ×12 + 獎(jiǎng)金,獎(jiǎng)金為空則按 0 算)并排序
SELECT ename, sal*12+IFNULL(comm,0) AS '年薪' FROM EMP ORDER BY 年薪 DESC;
查詢結(jié)果:
| ename | 年薪 |
|---|---|
| KING | 60000 |
| SCOTT | 36000 |
| FORD | 36000 |
| JONES | 35700 |
| BLAKE | 34200 |
| CLARK | 29400 |
| ALLEN | 19500 |
| TURNER | 18000 |
| MARTIN | 16400 |
| MILLER | 15600 |
| WARD | 15500 |
| ADAMS | 13200 |
| JAMES | 11400 |
| SMITH | 9600 |
3. 聚合與分組查詢
(1)查每個(gè)部門的平均工資、最高工資
SELECT deptno, FORMAT(AVG(sal),2) AS avg_sal, MAX(sal) AS max_sal FROM EMP GROUP BY deptno;
查詢結(jié)果:
| deptno | avg_sal | max_sal |
|---|---|---|
| 10 | 2,916.67 | 5000 |
| 20 | 2,175.00 | 3000 |
| 30 | 1,566.67 | 2850 |
(2)篩選平均工資 < 2000的部門
SELECT deptno, AVG(sal) AS avg_sal FROM EMP GROUP BY deptno HAVING avg_sal<2000;
查詢結(jié)果:
| deptno | avg_sal |
|---|---|
| 30 | 1566.6667 |
二、多表查詢:跨表關(guān)聯(lián)數(shù)據(jù)
先明確關(guān)聯(lián)表基礎(chǔ)數(shù)據(jù):
DEPT部門表
| deptno | dname | loc |
|---|---|---|
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
SALGRADE工資級(jí)別表
| grade | losal | hisal |
|---|---|---|
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
1. 基礎(chǔ)多表聯(lián)查(等值連接)
(1)查 “員工名、工資、所屬部門名”
SELECT EMP.ename, EMP.sal, DEPT.dname FROM EMP, DEPT WHERE EMP.deptno = DEPT.deptno;
查詢結(jié)果(節(jié)選):
| ename | sal | dname |
|---|---|---|
| SMITH | 800 | RESEARCH |
| ALLEN | 1600 | SALES |
| WARD | 1250 | SALES |
| JONES | 2975 | RESEARCH |
| MARTIN | 1250 | SALES |
| BLAKE | 2850 | SALES |
| CLARK | 2450 | ACCOUNTING |
| SCOTT | 3000 | RESEARCH |
| KING | 5000 | ACCOUNTING |
| TURNER | 1500 | SALES |
| ADAMS | 1100 | RESEARCH |
| JAMES | 950 | SALES |
| FORD | 3000 | RESEARCH |
| MILLER | 1300 | ACCOUNTING |
(2)限定部門號(hào)為 10的員工
SELECT ename, sal, dname FROM EMP, DEPT WHERE EMP.deptno=DEPT.deptno AND DEPT.deptno=10;
查詢結(jié)果:
| ename | sal | dname |
|---|---|---|
| CLARK | 2450 | ACCOUNTING |
| KING | 5000 | ACCOUNTING |
| MILLER | 1300 | ACCOUNTING |
2. 三表聯(lián)查(含工資級(jí)別表)
SELECT ename, sal, grade FROM EMP, SALGRADE WHERE EMP.sal BETWEEN losal AND hisal;
查詢結(jié)果:
| ename | sal | grade |
|---|---|---|
| SMITH | 800 | 1 |
| ALLEN | 1600 | 3 |
| WARD | 1250 | 2 |
| JONES | 2975 | 4 |
| MARTIN | 1250 | 2 |
| BLAKE | 2850 | 4 |
| CLARK | 2450 | 4 |
| SCOTT | 3000 | 4 |
| KING | 5000 | 5 |
| TURNER | 1500 | 3 |
| ADAMS | 1100 | 1 |
| JAMES | 950 | 1 |
| FORD | 3000 | 4 |
| MILLER | 1300 | 2 |
三、自連接:同一張表查上下級(jí)
-- 別名leader代表領(lǐng)導(dǎo),worker代表員工 SELECT leader.empno, leader.ename FROM emp leader, emp worker WHERE leader.empno = worker.mgr AND worker.ename='FORD';
查詢結(jié)果:
| empno | ename |
|---|---|
| 7566 | JONES |
四、子查詢:用查詢結(jié)果當(dāng)條件 / 臨時(shí)表
1. 單行子查詢(返回一條結(jié)果)
SELECT ename, job FROM EMP WHERE sal = (SELECT MAX(sal) FROM EMP);
查詢結(jié)果:
| ename | job |
|---|---|
| KING | PRESIDENT |
2. 多行子查詢(返回多條結(jié)果)
(1)查 “和 10 號(hào)部門崗位相同、但不屬于 10 號(hào)部門” 的員工
SELECT ename,job,sal,deptno FROM emp WHERE job IN (SELECT DISTINCT job FROM emp WHERE deptno=10) AND deptno<>10;
查詢結(jié)果:
| ename | job | sal | deptno |
|---|---|---|---|
| JONES | MANAGER | 2975 | 20 |
| BLAKE | MANAGER | 2850 | 30 |
| SMITH | CLERK | 800 | 20 |
| ADAMS | CLERK | 1100 | 20 |
| JAMES | CLERK | 950 | 30 |
(2)查 “工資比 30 號(hào)部門所有員工都高” 的員工
SELECT ename, sal, deptno FROM EMP WHERE sal > ALL(SELECT sal FROM EMP WHERE deptno=30);
查詢結(jié)果:
| ename | sal | deptno |
|---|---|---|
| JONES | 2975 | 20 |
| SCOTT | 3000 | 20 |
| KING | 5000 | 10 |
| FORD | 3000 | 20 |
3. from 子句子查詢(把子查詢當(dāng)臨時(shí)表)
-- 先查各部門平均工資(臨時(shí)表tmp),再關(guān)聯(lián)員工表 SELECT ename, deptno, sal, FORMAT(tmp.avg_sal,2) AS dept_avg_sal FROM EMP, (SELECT AVG(sal) avg_sal, deptno dt FROM EMP GROUP BY deptno) tmp WHERE EMP.sal > tmp.avg_sal AND EMP.deptno=tmp.dt;
查詢結(jié)果:
| ename | deptno | sal | dept_avg_sal |
|---|---|---|---|
| KING | 10 | 5000 | 2,916.67 |
| JONES | 20 | 2975 | 2,175.00 |
| SCOTT | 20 | 3000 | 2,175.00 |
| FORD | 20 | 3000 | 2,175.00 |
| BLAKE | 30 | 2850 | 1,566.67 |
| ALLEN | 30 | 1600 | 1,566.67 |
五、合并查詢:union/union all
1. union(自動(dòng)去重)
SELECT ename, sal, job FROM EMP WHERE sal>2500 UNION SELECT ename, sal, job FROM EMP WHERE job='MANAGER';
查詢結(jié)果(無重復(fù)數(shù)據(jù)):
| ename | sal | job |
|---|---|---|
| JONES | 2975 | MANAGER |
| BLAKE | 2850 | MANAGER |
| SCOTT | 3000 | ANALYST |
| KING | 5000 | PRESIDENT |
| FORD | 3000 | ANALYST |
| CLARK | 2450 | MANAGER |
2. union all(保留重復(fù))
SELECT ename, sal, job FROM EMP WHERE sal>2500 UNION ALL SELECT ename, sal, job FROM EMP WHERE job='MANAGER';
查詢結(jié)果(JONES、BLAKE 重復(fù)出現(xiàn)):
| ename | sal | job |
|---|---|---|
| JONES | 2975 | MANAGER |
| BLAKE | 2850 | MANAGER |
| SCOTT | 3000 | ANALYST |
| KING | 5000 | PRESIDENT |
| FORD | 3000 | ANALYST |
| JONES | 2975 | MANAGER |
| BLAKE | 2850 | MANAGER |
| CLARK | 2450 | MANAGER |
總結(jié)
MySQL 復(fù)合查詢是實(shí)際開發(fā)的核心技能,核心是理清表關(guān)系、靈活組合單表 / 多表 / 子查詢語(yǔ)法。
本文所有示例均基于真實(shí)員工管理表數(shù)據(jù),查詢結(jié)果可直接驗(yàn)證,建議你復(fù)制 SQL 語(yǔ)句在本地?cái)?shù)據(jù)庫(kù)中實(shí)操,更快掌握各類查詢技巧~
這些僅為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL中的CONCAT()函數(shù):輕松拼接字符串的利器
這篇文章主要介紹了MySQL中的CONCAT()函數(shù):輕松拼接字符串的利器,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
解決windows下mysql8修改my.ini設(shè)置datadir后無法啟動(dòng)問題
在修改MySQL的my.ini文件以更改數(shù)據(jù)目錄后,可能會(huì)遇到無法啟動(dòng)的問題,這通常是因?yàn)樽址幋a被改變或新路徑權(quán)限不足,正確的做法是備份my.ini文件,確保使用ANSI字符編碼修改datadir,并確保新路徑有足夠的權(quán)限,特別是SYSTEM或NETWORKSERVICE權(quán)限2025-01-01
詳解一條sql語(yǔ)句在mysql中是如何執(zhí)行的
這篇文章主要介紹了一條sql語(yǔ)句在mysql中是如何執(zhí)行的,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
關(guān)閉和打開本地的mysql實(shí)現(xiàn)方式
這篇文章主要介紹了關(guān)閉和打開本地的mysql實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
MySQL數(shù)據(jù)庫(kù)誤刪恢復(fù)的超詳細(xì)教程
MySQL誤刪數(shù)據(jù)庫(kù),造成了數(shù)據(jù)的丟失,這是非常尷尬的,但是有許多方案可以用來嘗試恢復(fù)丟失的數(shù)據(jù)庫(kù),這篇文章主要給大家介紹了關(guān)于MySQL數(shù)據(jù)庫(kù)誤刪恢復(fù)的超詳細(xì)教程,需要的朋友可以參考下2024-03-03
MySQL實(shí)戰(zhàn)之Insert語(yǔ)句的使用心得
這篇文章主要給大家介紹了關(guān)于MySQL實(shí)戰(zhàn)之Insert語(yǔ)句的使用心得的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
解決mysql服務(wù)器在無操作超時(shí)主動(dòng)斷開連接的情況
這篇文章主要介紹了解決mysql服務(wù)器在無操作超時(shí)主動(dòng)斷開連接的情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07

