MySQL 多表連接查詢實(shí)戰(zhàn)指南:內(nèi)連接 + 外連接
前言:
在實(shí)際業(yè)務(wù)開發(fā)中,數(shù)據(jù)往往分散存儲(chǔ)在多張關(guān)聯(lián)表中,單表查詢遠(yuǎn)不能滿足復(fù)雜的統(tǒng)計(jì)與展示需求。多表連接查詢正是解決跨表數(shù)據(jù)關(guān)聯(lián)、整合與展示的核心手段,也是數(shù)據(jù)庫(kù)開發(fā)中最常用、最重要的技能之一。本文將圍繞 MySQL 內(nèi)連接、左外連接、右外連接 的核心語(yǔ)法與使用場(chǎng)景,結(jié)合經(jīng)典案例由淺入深精講,幫你快速掌握多表查詢的精髓,輕松應(yīng)對(duì)日常開發(fā)與面試。
一. 什么是表連接?為什么要用連接?
在實(shí)際開發(fā)中,數(shù)據(jù)不可能都放在一張表里,而是分散在多張關(guān)聯(lián)表中。舉個(gè)直觀例子:
- 學(xué)生表(
stu):存儲(chǔ)學(xué)生 id 和姓名,無法直接體現(xiàn)成績(jī); - 成績(jī)表(
exam):存儲(chǔ)學(xué)生 id 和分?jǐn)?shù),無法直接關(guān)聯(lián)學(xué)生姓名。
如果想同時(shí)展示 “學(xué)生姓名 + 對(duì)應(yīng)成績(jī)”,或 “所有學(xué)生的成績(jī)(含無成績(jī)的學(xué)生)”,就必須通過表連接將兩張表的關(guān)聯(lián)字段(如 id)綁定,實(shí)現(xiàn)數(shù)據(jù)聯(lián)動(dòng)查詢。
表連接的核心價(jià)值:打破表的孤立性,整合多表關(guān)聯(lián)數(shù)據(jù),滿足復(fù)雜業(yè)務(wù)查詢需求。
二. 內(nèi)連接(inner join):取兩表交集
內(nèi)連接是最常用的連接方式,核心邏輯是只保留兩張表中關(guān)聯(lián)條件匹配成功的數(shù)據(jù),相當(dāng)于 “取兩表的交集”。
2.1 語(yǔ)法(標(biāo)準(zhǔn)寫法)
select 字段名 from 表1 inner join 表2 on 連接條件 and 其他篩選條件;
inner join:內(nèi)連接關(guān)鍵字(inner可省略,直接寫join);on:指定表之間的關(guān)聯(lián)條件(如兩表的主鍵 / 外鍵關(guān)聯(lián));- 區(qū)別于老式的
where篩選,on更清晰地分離 “連接條件” 和 “業(yè)務(wù)篩選條件”。
2.2 PPT 實(shí)戰(zhàn)案例:查詢 SMITH 的姓名和部門名稱
已知員工表(emp)和部門表(dept)通過deptno字段關(guān)聯(lián),需求:查詢員工 SMITH 的姓名和所屬部門名稱。
-- 標(biāo)準(zhǔn)內(nèi)連接寫法 select ename, dname from emp inner join dept on emp.deptno = dept.deptno -- 連接條件:兩表部門號(hào)一致 and ename = 'smith'; -- 業(yè)務(wù)篩選條件:?jiǎn)T工姓名為smith -- 等價(jià)于老式寫法(不推薦,連接邏輯不清晰) select ename, dname from emp, dept where emp.deptno = dept.deptno and ename = 'smith';
2.3 內(nèi)連接特點(diǎn)
- 只顯示兩表中匹配成功的數(shù)據(jù),匹配失敗的記錄會(huì)被過濾;
- 關(guān)聯(lián)條件是核心,若缺少
on或where篩選,會(huì)產(chǎn)生笛卡爾積(數(shù)據(jù)量爆炸,無意義); - 適用于需要 “僅展示有效關(guān)聯(lián)數(shù)據(jù)” 的場(chǎng)景(如查詢有部門的員工、有成績(jī)的學(xué)生)。
三. 外連接:保留某張表的全部數(shù)據(jù)
外連接的核心是保留其中一張表的全部數(shù)據(jù),另一張表匹配不到則顯示 null,分為左外連接和右外連接,適用于 “需完整展示主表數(shù)據(jù)” 的場(chǎng)景。
3.1 左外連接(left join):保留左表全部數(shù)據(jù)
左外連接規(guī)則:左表的所有記錄都會(huì)顯示,右表僅顯示匹配成功的記錄,匹配失敗則字段值為 null。
3.1.1 語(yǔ)法
select 字段名 from 表1 -- 左表(需完整保留的表) left join 表2 -- 右表(匹配表) on 連接條件;
3.1.2 實(shí)戰(zhàn)案例:查詢所有學(xué)生的成績(jī)(含無成績(jī)的學(xué)生)
- 先創(chuàng)建測(cè)試表并插入數(shù)據(jù):
-- 創(chuàng)建學(xué)生表 create table stu ( id int, name varchar(30) ); -- 插入學(xué)生數(shù)據(jù) insert into stu values (1,'jack'), (2,'tom'), (3,'kity'), (4,'nono'); -- 創(chuàng)建成績(jī)表 create table exam ( id int, grade int ); -- 插入成績(jī)數(shù)據(jù)(注意:id=11無對(duì)應(yīng)學(xué)生) insert into exam values (1,56), (2,76), (11,8);
- 左外連接查詢(保留所有學(xué)生,無成績(jī)顯示 null):
select * from stu left join exam on stu.id = exam.id; -- 連接條件:學(xué)生id與成績(jī)表id一致
- 查詢結(jié)果
| id | name | id | grade |
|---|---|---|---|
| 1 | jack | 1 | 56 |
| 2 | tom | 2 | 76 |
| 3 | kity | null | null |
| 4 | nono | null | null |
可以看到:左表(stu)的 4 名學(xué)生全部顯示,即使 kity 和 nono 沒有成績(jī)(右表無匹配數(shù)據(jù)),也保留了他們的個(gè)人信息。
3.2 右外連接(right join):保留右表全部數(shù)據(jù)
右外連接規(guī)則:右表的所有記錄都會(huì)顯示,左表僅顯示匹配成功的記錄,匹配失敗則字段值為 null。
3.2.1 語(yǔ)法
select 字段名 from 表1 -- 左表(匹配表) right join 表2 -- 右表(需完整保留的表) on 連接條件;
3.2.2 實(shí)戰(zhàn)案例:查詢所有成績(jī)(含無對(duì)應(yīng)學(xué)生的成績(jī))
需求:顯示所有成績(jī)記錄,即使該成績(jī)沒有對(duì)應(yīng)的學(xué)生(如 exam 中 id=11 的成績(jī))。
select * from stu right join exam on stu.id = exam.id; -- 連接條件:學(xué)生id與成績(jī)表id一致
3.2.3 查詢結(jié)果:
| id | name | id | grade |
|---|---|---|---|
| 1 | jack | 1 | 56 |
| 2 | tom | 2 | 76 |
| null | null | 11 | 8 |
可以看到:右表(exam)的 3 條成績(jī)?nèi)匡@示,即使 id=11 的成績(jī)沒有對(duì)應(yīng)學(xué)生(左表無匹配數(shù)據(jù)),也保留了該成績(jī)記錄。
四. 綜合實(shí)戰(zhàn):列出部門及員工(含無員工的部門)
需求:查詢所有部門名稱及對(duì)應(yīng)員工信息,即使某個(gè)部門沒有員工,也需要顯示該部門名稱。
已知:部門表(dept)和員工表(emp)通過deptno字段關(guān)聯(lián),兩種實(shí)現(xiàn)方式如下:
4.1 方法一:左外連接(以部門表為左表)
select d.dname, e.* from dept d -- 左表:部門表(需完整保留) left join emp e -- 右表:?jiǎn)T工表(匹配表) on d.deptno = e.deptno; -- 連接條件:部門號(hào)一致
4.2 方法二:右外連接(以部門表為右表)
select d.dname, e.* from emp e -- 左表:?jiǎn)T工表(匹配表) right join dept d -- 右表:部門表(需完整保留) on d.deptno = e.deptno; -- 連接條件:部門號(hào)一致
兩種方法結(jié)果完全一致:所有部門都會(huì)顯示,無員工的部門對(duì)應(yīng)的員工字段(e.*)會(huì)顯示 null。
五. 內(nèi)外連接核心區(qū)別(一張表看懂)
| 連接類型 | 核心邏輯 | 關(guān)鍵字 | 適用場(chǎng)景 |
|---|---|---|---|
| 內(nèi)連接 | 只保留兩表匹配成功的數(shù)據(jù) | inner join | 查詢有效關(guān)聯(lián)數(shù)據(jù)(如有部門的員工) |
| 左外連接 | 保留左表全部數(shù)據(jù),右表匹配不到顯示 null | left join | 完整展示左表數(shù)據(jù)(如所有學(xué)生成績(jī)) |
| 右外連接 | 保留右表全部數(shù)據(jù),左表匹配不到顯示 null | right join | 完整展示右表數(shù)據(jù)(如所有成績(jī)記錄) |
六. 避坑指南和總結(jié)(開發(fā)必備)
- 連接條件不可少:忘記
on或where篩選會(huì)產(chǎn)生笛卡爾積(如 stu 表 4 條數(shù)據(jù) + exam 表 3 條數(shù)據(jù) = 12 條無效數(shù)據(jù)); on與where的區(qū)別:on用于指定 “表連接條件”,where用于篩選 “連接后的結(jié)果集”,邏輯上先執(zhí)行on再執(zhí)行where;- 字段歧義需加別名:當(dāng)兩表有同名字段(如 id),查詢時(shí)需用
表別名.字段名區(qū)分(如stu.id、exam.id); - 外連接的 “主表” 選擇:需完整保留數(shù)據(jù)的表作為左表(左連接)或右表(右連接),避免搞反導(dǎo)致數(shù)據(jù)丟失。
總結(jié):
MySQL 多表連接是日常開發(fā)的核心技能,核心要點(diǎn)總結(jié):
- 內(nèi)連接(inner join):取兩表交集,適用于有效關(guān)聯(lián)數(shù)據(jù)查詢;
- 左外連接(left join):保留左表全部數(shù)據(jù),適用于完整展示主表 + 關(guān)聯(lián)數(shù)據(jù);
- 右外連接(right join):保留右表全部數(shù)據(jù),與左連接可靈活轉(zhuǎn)換;
- 所有連接查詢需明確 “連接條件”,避免笛卡爾積,字段歧義加別名。
結(jié)尾:
到此這篇關(guān)于MySQL 多表連接查詢實(shí)戰(zhàn)指南:內(nèi)連接 + 外連接的文章就介紹到這了,更多相關(guān)mysql多表連接查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MySQL多表查詢內(nèi)連接外連接詳解(使用join、left?join、right?join和full?join)
- 詳解MySQL數(shù)據(jù)庫(kù)--多表查詢--內(nèi)連接,外連接,子查詢,相關(guān)子查詢
- MySQL增刪查改、多表查詢的操作大全
- MySQL 多表聯(lián)合查詢與數(shù)據(jù)備份恢復(fù)全攻略
- MySQL多表查詢示例詳解
- MySQL數(shù)據(jù)庫(kù)約束和多表查詢實(shí)例代碼
- MySQL復(fù)雜查詢優(yōu)化實(shí)戰(zhàn)之從多表關(guān)聯(lián)到子查詢的性能突破(全流程)
- MySQL復(fù)雜SQL之多表聯(lián)查/子查詢?cè)敿?xì)介紹(最新整理)
相關(guān)文章
MySQL兩個(gè)查詢?nèi)绾魏喜⒊梢粋€(gè)結(jié)果詳解
利用union關(guān)鍵字,可以給出多條select語(yǔ)句,并將它們的結(jié)果組合成單個(gè)結(jié)果集,下面這篇文章主要給大家介紹了關(guān)于MySQL兩個(gè)查詢?nèi)绾魏喜⒊梢粋€(gè)結(jié)果的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
檢查mysql是否成功啟動(dòng)的方法(bat+bash)
這篇文章主要介紹了檢查mysql是否成功啟動(dòng)的方法(bat+bash),如果mysql沒有啟動(dòng)則開啟服務(wù),需要的朋友可以參考下2016-06-06
MySQL在關(guān)聯(lián)復(fù)雜情況下所能做出的一些優(yōu)化
這篇文章主要介紹了MySQL在關(guān)聯(lián)復(fù)雜情況下所能做出的一些優(yōu)化,作者通過添加索引來不斷優(yōu)化查詢時(shí)間,需要的朋友可以參考下2015-05-05

