SQL 中多表查詢的常見(jiàn)連接方式詳解
以下是用圖表結(jié)合代碼解釋 SQL 中多表查詢的常見(jiàn)連接方式:
一、連接類型圖表(ASCII 形式)
1. 內(nèi)連接 (INNER JOIN)
+-------------+ +-------------+
| Table A | | Table B |
+-------------+ +-------------+
| 交集部分 |
+-----------+
2. 左連接 (LEFT JOIN)
+-------------+ +-------------+
| Table A | | Table B |
+-------------+ +-------------+
| 全部保留 |
| 右表匹配 |
3. 右連接 (RIGHT JOIN)
+-------------+ +-------------+
| Table A | | Table B |
+-------------+ +-------------+
| 左表匹配 |
| 全部保留 |
4. 全外連接 (FULL OUTER JOIN)
+-------------+ +-------------+
| Table A | | Table B |
+-------------+ +-------------+
| 全部保留 |
| 全部保留 |二、前置代碼(創(chuàng)建示例表)
-- 創(chuàng)建示例表 CREATE TABLE employees ( id INT PRIMARY KEY, name VARCHAR(50), dept_id INT ); CREATE TABLE departments ( id INT PRIMARY KEY, dept_name VARCHAR(50) ); -- 插入測(cè)試數(shù)據(jù) INSERT INTO employees VALUES (1, 'Alice', 101), (2, 'Bob', 102), (3, 'Charlie', 103), (4, 'David', NULL); INSERT INTO departments VALUES (101, 'HR'), (102, 'Engineering'), (104, 'Marketing');
三、連接方式代碼示例
1. 內(nèi)連接(INNER JOIN)
SELECT e.name AS 員工姓名, -- 從 employees 表中選擇員工姓名 d.dept_name AS 部門(mén)名稱 -- 從 departments 表中選擇部門(mén)名稱 FROM employees e -- 主表:employees(別名為 e) INNER JOIN departments d -- 連接表:departments(別名為 d) ON e.dept_id = d.id; -- 連接條件:?jiǎn)T工的部門(mén)ID = 部門(mén)的ID
分步圖解
假設(shè)表中數(shù)據(jù)如下(基于你之前創(chuàng)建的測(cè)試數(shù)據(jù)):
表 employees
| id | name | dept_id |
|---|---|---|
| 1 | Alice | 101 |
| 2 | Bob | 102 |
| 3 | Charlie | 103 |
| 4 | David | NULL |
表 departments
| id | dept_name |
|---|---|
| 101 | HR |
| 102 | Engineering |
| 104 | Marketing |
連接過(guò)程
employees(e) departments(d) +----+---------+---------+ +-----+-------------+ | id | name | dept_id | | id | dept_name | +----+---------+---------+ +-----+-------------+ | 1 | Alice | 101 | | 101 | HR | | 2 | Bob | 102 | | 102 | Engineering | | 3 | Charlie | 103 | | 104 | Marketing | | 4 | David | NULL | +-----+-------------+ +----+---------+---------+ 通過(guò) INNER JOIN 連接條件 e.dept_id = d.id:
- Alice(dept_id=101)→ 匹配到 d.id=101(HR)→ 保留記錄
- Bob(dept_id=102)→ 匹配到 d.id=102(Engineering)→ 保留記錄
- Charlie(dept_id=103)→ departments 表中無(wú) id=103 → 排除
- David(dept_id=NULL)→ 無(wú)法匹配 → 排除
- Marketing(id=104)→ employees 表中無(wú) dept_id=104 → 排除
關(guān)鍵概念解釋
1. INNER JOIN 的作用
- 僅保留兩個(gè)表中匹配的記錄
- 如果員工的
dept_id在departments表中找不到對(duì)應(yīng)的id,該員工會(huì)被排除 - 如果部門(mén)在
employees表中無(wú)人歸屬,該部門(mén)也會(huì)被排除
2. 為什么用 e.dept_id = d.id?
- 這是兩個(gè)表之間的關(guān)聯(lián)關(guān)系:?jiǎn)T工的部門(mén)編號(hào)(
dept_id)必須等于部門(mén)的主鍵(id)
3. 別名(e 和 d)的作用
- 簡(jiǎn)化表名書(shū)寫(xiě)(
employees e= 給表起別名e) - 明確字段來(lái)源(例如
e.name表示來(lái)自員工表,d.dept_name表示來(lái)自部門(mén)表)
結(jié)果輸出
| 員工姓名 | 部門(mén)名稱 |
|---|---|
| Alice | HR |
| Bob | Engineering |
結(jié)果說(shuō)明
- Charlie 被排除:因?yàn)?nbsp;
dept_id=103在departments表中不存在 - David 被排除:因?yàn)?nbsp;
dept_id=NULL無(wú)法匹配任何部門(mén) - Marketing 部門(mén) 被排除:因?yàn)闆](méi)有員工的
dept_id=104
2. 左連接(LEFT JOIN)
SELECT e.name, d.dept_name FROM employees e LEFT JOIN departments d ON e.dept_id = d.id;
結(jié)果: 包含所有左表記錄 + 右表匹配結(jié)果(David 的部門(mén)為 NULL)
3. 右連接(RIGHT JOIN)
SELECT e.name, d.dept_name FROM employees e RIGHT JOIN departments d ON e.dept_id = d.id;
結(jié)果: 包含所有右表記錄 + 左表匹配結(jié)果(Marketing 部門(mén)無(wú)員工)
4. 全外連接(FULL OUTER JOIN)
-- MySQL 不支持 FULL OUTER JOIN,需用 UNION 模擬 SELECT e.name, d.dept_name FROM employees e LEFT JOIN departments d ON e.dept_id = d.id UNION SELECT e.name, d.dept_name FROM employees e RIGHT JOIN departments d ON e.dept_id = d.id;
結(jié)果: 包含所有記錄(含 NULL 匹配)
5. 交叉連接(CROSS JOIN)
SELECT e.name, d.dept_name FROM employees e CROSS JOIN departments d;
結(jié)果: 笛卡爾積(4 員工 × 3 部門(mén) = 12 條記錄)
四、結(jié)果對(duì)比表
| 連接類型 | 結(jié)果記錄數(shù) | 包含 NULL 情況 |
|---|---|---|
| INNER JOIN | 2 | 無(wú) |
| LEFT JOIN | 4 | 右表可能為 NULL |
| RIGHT JOIN | 3 | 左表可能為 NULL |
| FULL OUTER JOIN | 5 | 兩側(cè)均可能為 NULL |
| CROSS JOIN | 12 | 無(wú)關(guān)聯(lián)條件,純組合 |
五、關(guān)鍵點(diǎn)總結(jié)
- INNER JOIN 僅保留匹配記錄
- LEFT/RIGHT JOIN 保留一側(cè)全部記錄
- FULL OUTER JOIN 保留兩側(cè)所有記錄
- CROSS JOIN 生成笛卡爾積
- 處理 NULL 值時(shí)需注意
COALESCE()或IFNULL()函數(shù)的使用
可以通過(guò)實(shí)際運(yùn)行這些 SQL 語(yǔ)句觀察不同連接方式的差異。
PS、自連接示意圖(ASCII 形式)
自連接 (SELF JOIN)
+-------------+ +-------------+
| Table | | Table |
| (別名為A) | | (別名為B) |
+-------------+ +-------------+
| 關(guān)聯(lián)自身的字段 |
+----------------+典型場(chǎng)景:?jiǎn)T工表查詢上下級(jí)關(guān)系、分類層級(jí)關(guān)系等
二、前置代碼(創(chuàng)建帶層級(jí)關(guān)系的表)
-- 創(chuàng)建帶 manager_id 的員工表 CREATE TABLE employees ( id INT PRIMARY KEY, name VARCHAR(50), manager_id INT ); -- 插入測(cè)試數(shù)據(jù) INSERT INTO employees VALUES (1, 'Alice', NULL), -- 頂級(jí)管理者 (2, 'Bob', 1), -- 向 Alice 匯報(bào) (3, 'Charlie', 1), -- 向 Alice 匯報(bào) (4, 'David', 2); -- 向 Bob 匯報(bào)
三、自連接代碼示例
1. 查詢員工及其上級(jí)(左連接版)
SELECT e.name AS employee, m.name AS manager FROM employees e LEFT JOIN employees m ON e.manager_id = m.id;
結(jié)果:
+----------+----------+
| employee | manager |
+----------+----------+
| Alice | NULL | -- 沒(méi)有上級(jí)
| Bob | Alice |
| Charlie | Alice |
| David | Bob |
+----------+----------+
2. 僅查詢有上級(jí)的員工(內(nèi)連接版)
SELECT e.name AS employee, m.name AS manager FROM employees e INNER JOIN employees m ON e.manager_id = m.id;
結(jié)果:
+----------+---------+
| employee | manager |
+----------+---------+
| Bob | Alice |
| Charlie | Alice |
| David | Bob |
+----------+---------+
四、結(jié)果對(duì)比表
| 連接方式 | 結(jié)果記錄數(shù) | 包含 NULL 情況 | 典型用途 |
|---|---|---|---|
| 自連接-左連接 | 4 | 頂級(jí)管理者的上級(jí)為 NULL | 顯示完整層級(jí)結(jié)構(gòu) |
| 自連接-內(nèi)連接 | 3 | 無(wú) NULL | 僅顯示有上下級(jí)關(guān)系的記錄 |
五、關(guān)鍵點(diǎn)總結(jié)
- 自連接本質(zhì):將同一張表視為兩個(gè)邏輯表進(jìn)行連接
- 必須使用別名:區(qū)分不同角色的表實(shí)例(如
e為員工,m為上級(jí)) - 常用場(chǎng)景:
- 組織結(jié)構(gòu)查詢(員工 ↔ 上級(jí))
- 分類層級(jí)(父分類 ↔ 子分類)
- 路徑分析(如路線 A → B → C)
4.NULL 處理:
SELECT e.name, COALESCE(m.name, '頂級(jí)管理者') AS manager FROM employees e LEFT JOIN employees m ON e.manager_id = m.id;
到此這篇關(guān)于SQL 中多表查詢的常見(jiàn)連接方式詳解的文章就介紹到這了,更多相關(guān)sql多表查詢連接方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入SQLServer中ISNULL與NULLIF的使用詳解
本篇文章是對(duì)SQLServer中ISNULL與NULLIF的使用進(jìn)行了詳細(xì)分析介紹,需要的朋友參考下2013-06-06
SQL Server 中查看SQL句子執(zhí)行所用的時(shí)間
在MSSQL Server中通過(guò)查看SQL語(yǔ)句執(zhí)行所用的時(shí)間,來(lái)衡量SQL語(yǔ)句的性能。2009-07-07
高并發(fā)系統(tǒng)數(shù)據(jù)冪等的解決方案
本文主要介紹高并發(fā)系統(tǒng)數(shù)據(jù)冪等解決方案,這里整理了幾種方案供大家參考,有需要的小伙伴可以參考下2016-08-08
SQL SERVER如何判斷某個(gè)字段包含大寫(xiě)字母
本文將詳細(xì)介紹SQL SERVER如何判斷某個(gè)字段包含大寫(xiě)字母的方法,需要的朋友可以參考下2012-11-11
MSSQL 計(jì)算兩個(gè)日期相差的工作天數(shù)的語(yǔ)句
MSSQL計(jì)算兩個(gè)日期相差的工作天數(shù)的代碼,需要的朋友可以參考下。2009-09-09

