前言
在日常的數(shù)據(jù)庫(kù)使用過(guò)程中,我們處理的數(shù)據(jù)不只是單張表,而是需要我們同時(shí)處理多個(gè)表的數(shù)據(jù),那么今天我將為大家分享關(guān)于MySQL的多表操作。
多表關(guān)系
在學(xué)習(xí)多表操作之前,我們需要知道有哪些多表關(guān)系:一對(duì)一關(guān)系、一對(duì)多關(guān)系/多對(duì)一關(guān)系、多對(duì)多關(guān)系。
一對(duì)一關(guān)系
一對(duì)一關(guān)系是指一個(gè)表的一條記錄只能對(duì)應(yīng)另外一個(gè)表的一條記錄,它們之間通過(guò)共同的主鍵或唯一鍵進(jìn)行關(guān)聯(lián)。
一對(duì)多/多對(duì)一關(guān)系
多表一對(duì)多或多對(duì)一關(guān)系是指一個(gè)表的一條記錄可以對(duì)應(yīng)另一個(gè)表的多條記錄,它們之間通過(guò)共同的主鍵或外鍵進(jìn)行關(guān)聯(lián)。
多對(duì)多關(guān)系
多表多對(duì)多關(guān)系是指兩個(gè)或多個(gè)表之間相互關(guān)聯(lián),并且每個(gè)表的記錄可以對(duì)應(yīng)其他表的多個(gè)記錄。處理多表多對(duì)多關(guān)系的常見(jiàn)方法是使用中間表(關(guān)聯(lián)表)來(lái)連接關(guān)系。
外鍵約束
MySQL外鍵約束是一種數(shù)據(jù)庫(kù)約束,用于確保表之間的關(guān)系的完整性。它定義了一個(gè)字段或一組字段在一個(gè)表中的值必須與另一個(gè)表中的值保持一致,或滿足特定條件。
外鍵約束通過(guò)指定一個(gè)外鍵關(guān)系,將一個(gè)表的字段(稱為外鍵)與另一個(gè)表的主鍵或唯一鍵(稱為參照鍵)進(jìn)行關(guān)聯(lián)。這樣,如果某個(gè)表中的外鍵值發(fā)生改變,MySQL會(huì)自動(dòng)檢查參照表中是否存在匹配的鍵值,以保持?jǐn)?shù)據(jù)的一致性。
外鍵約束有以下幾個(gè)作用:
- 強(qiáng)制引用完整性:外鍵約束確保表中的數(shù)據(jù)在引用時(shí)存在于關(guān)聯(lián)表中。
- 維護(hù)數(shù)據(jù)一致性:外鍵約束防止在關(guān)聯(lián)表中刪除或修改數(shù)據(jù)時(shí),引發(fā)不一致的結(jié)果。
- 提供查詢優(yōu)化:MySQL優(yōu)化器可以使用外鍵關(guān)系來(lái)加速查詢操作。
- 級(jí)聯(lián)操作:外鍵約束可以定義級(jí)聯(lián)操作,當(dāng)參照表中的數(shù)據(jù)更新或刪除時(shí),自動(dòng)對(duì)關(guān)聯(lián)表中的數(shù)據(jù)進(jìn)行相應(yīng)操作。
MySQL外鍵約束具有以下特點(diǎn):
-
強(qiáng)制引用完整性:外鍵約束確保引用表中的數(shù)據(jù)在被引用表中存在,防止出現(xiàn)無(wú)效的引用。這可以保證數(shù)據(jù)的一致性和完整性。
-
自動(dòng)驗(yàn)證和維護(hù)關(guān)系:MySQL會(huì)自動(dòng)驗(yàn)證和維護(hù)外鍵約束,確保關(guān)聯(lián)的數(shù)據(jù)被正確更新、插入或刪除。如果違反了外鍵約束,MySQL會(huì)報(bào)錯(cuò)并拒絕執(zhí)行操作。
-
支持級(jí)聯(lián)操作:外鍵約束可以定義級(jí)聯(lián)操作,在參照表中進(jìn)行刪除或更新操作時(shí),自動(dòng)對(duì)關(guān)聯(lián)表中相關(guān)的數(shù)據(jù)進(jìn)行相應(yīng)操作。例如,可以實(shí)現(xiàn)級(jí)聯(lián)刪除,刪除參照表中的數(shù)據(jù)時(shí),同時(shí)刪除關(guān)聯(lián)表中的相關(guān)數(shù)據(jù)。
-
優(yōu)化查詢性能:MySQL優(yōu)化器可以使用外鍵約束來(lái)優(yōu)化查詢操作。通過(guò)正確設(shè)置外鍵關(guān)系,MySQL可以更有效地執(zhí)行JOIN操作,提高查詢性能。
-
可以禁用和啟用:需要時(shí),可以禁用或啟用外鍵約束,以允許執(zhí)行某些需要暫時(shí)違反外鍵約束的操作。這個(gè)特性在某些情況下很有用,但需要謹(jǐn)慎使用,以防止數(shù)據(jù)不一致。
-
對(duì)數(shù)據(jù)完整性的依賴:使用外鍵約束可以在數(shù)據(jù)庫(kù)級(jí)別維護(hù)數(shù)據(jù)完整性,而不是依賴于應(yīng)用程序。這樣可以減少錯(cuò)誤和數(shù)據(jù)不一致的可能性,使數(shù)據(jù)庫(kù)更加可靠。
創(chuàng)建外鍵約束
MySQL 創(chuàng)建外鍵約束有兩種方式:1.在創(chuàng)建表的時(shí)候創(chuàng)建外鍵約束:create table 表名(列名1 類型,列名2 類型,constraint 外鍵名 foreign key(列名) references 主表(主表列名);
2.在創(chuàng)建表之后創(chuàng)建外鍵約束:alter table 表名 add constraint 外鍵名 foreign key(列名) referrnces 主表(主表列名);
我們?cè)趧?chuàng)建表之后添加外鍵約束的前提是:從表中外鍵列中的數(shù)據(jù)必須與主表中主鍵列中的數(shù)據(jù)一致或者是沒(méi)有數(shù)據(jù)。
在創(chuàng)建表的時(shí)候創(chuàng)建外鍵約束
create table class(class_id int primary key,name varchar(10)); -- 主表
insert into class values(1,'高三1班'),
(2,'高三2班'),
(3,'高三3班');
create table student
(class_id int,student_id int,name varchar(20),gender varchar(10),
constraint student_fk foreign key(class_id)
references class(class_id));
創(chuàng)建表之后添加外鍵約束
create table class(class_id int primary key,name varchar(10)); -- 主表
insert into class values(1,'高三1班'),
(2,'高三2班'),
(3,'高三3班');
create table student
(class_id int,student_id int,name varchar(20),gender varchar(10));
alter table student
add constraint student_fk
foreign key(class_id) references class(class_id);
插入數(shù)據(jù)
當(dāng)我們插入數(shù)據(jù)的時(shí)候,如果我們先向主表中插入數(shù)據(jù)的時(shí)候,不需要注意什么,但是當(dāng)我們向從表中插入數(shù)據(jù)的時(shí)候我們需要注意:插入的記錄的外鍵列的數(shù)據(jù)在主表的主鍵列中是否存在,如果存在,則插入成功,否則就插入失敗。所以建議:插入數(shù)據(jù)的時(shí)候先向主表中插入數(shù)據(jù),然后再向從表中插入數(shù)據(jù)。
insert into student values(1,2301,'張三','男');
insert into student values(4,2302,'王五','男');
如果我們?cè)谛陆ㄍ怄I約束的時(shí)候,表中已經(jīng)存在了數(shù)據(jù)該怎么辦?
create table student
(class_id int,student_id int,name varchar(20),gender varchar(10));
insert into student values(1,2301,'張三','男'),
(3,2302,'王五','男');
-- 我們插入的數(shù)據(jù)都是與主鍵列中的數(shù)據(jù)相對(duì)應(yīng)
alter table student
add constraint student_fk
foreign key(class_id) references class(class_id);
上面存在的數(shù)據(jù)外鍵列與主鍵列中的數(shù)據(jù)是相對(duì)應(yīng)的,所以插入成功。
create table student
(class_id int,student_id int,name varchar(20),gender varchar(10));
insert into student values(1,2301,'張三','男'),
(4,2302,'王五','男');
-- 這里class_id 4 在主鍵列中并不存在,我們看看是否能
alter table student
add constraint student_fk
foreign key(class_id) references class(class_id);
這里class_id 4 在主鍵列中并不存在,所以插入失敗。
刪除帶有外鍵約束的表的數(shù)據(jù)
如果我們需要?jiǎng)h除帶有外鍵約束的表中的數(shù)據(jù)該怎么辦呢?
- 刪除從表中的數(shù)據(jù)可以隨便刪除
- 當(dāng)我們刪除主表中的數(shù)據(jù)時(shí),我們需要注意:我們刪除的記錄的主鍵列還被外鍵列所依賴時(shí),不能刪除。
此時(shí)主鍵列 1 還被外鍵列依賴著,我們刪除試試。
delete from class where class_id = 1;
刪除失敗,所以我們刪除主表的數(shù)據(jù)時(shí),需要考慮該記錄的主鍵列是否還被外鍵列依賴著。在刪除數(shù)據(jù)的時(shí)候建議先刪除從表中的數(shù)據(jù),然后再刪除主表中未被依賴的數(shù)據(jù)
刪除外鍵約束
但我們不需要外鍵約束的時(shí)候,我們也可以刪除外鍵約束。alter table 表名 drop foreign key 外鍵名;
此時(shí)外鍵約束已刪除。
多表聯(lián)合查詢
多表查詢是 MySQL 操作中最重要也是使用最多的操作,所以我們需要學(xué)好 MySQL 多表查詢操作。
MySQL多表查詢是指在一個(gè)查詢語(yǔ)句中涉及到多個(gè)表,通過(guò)指定表之間的連接條件(關(guān)聯(lián)條件)來(lái)獲取聯(lián)合數(shù)據(jù)的過(guò)程。多表查詢可以用來(lái)檢索、過(guò)濾和組合來(lái)自多個(gè)表的數(shù)據(jù)。
MySQL多表操作主要包括:
- 交叉連接查詢
- 內(nèi)連接查詢
-
- 隱式內(nèi)連接(SQL92標(biāo)準(zhǔn))
-
- 顯式內(nèi)連接(SQL99標(biāo)準(zhǔn))
- 外連接
-
- 左外連接
-
- 右外連接
-
- 滿外連接
- 子查詢
- 自關(guān)聯(lián)查詢
并且我們實(shí)行的是查詢操作,外鍵約束不會(huì)對(duì)多表查詢?cè)斐捎绊憽?/p>
數(shù)據(jù)準(zhǔn)備
我們?yōu)楹竺娴亩啾聿樵儨?zhǔn)備數(shù)據(jù)。
use mydb3;
-- 創(chuàng)建部門(mén)表
create table if not exists dept3(
deptno varchar(20) primary key , -- 部門(mén)號(hào)
name varchar(20) -- 部門(mén)名字
);
-- 創(chuàng)建員工表
create table if not exists emp3(
eid varchar(20) primary key , -- 員工編號(hào)
ename varchar(20), -- 員工名字
age int, -- 員工年齡
dept_id varchar(20) -- 員工所屬部門(mén)
);
-- 給dept3表添加數(shù)據(jù)
insert into dept3 values('1001','研發(fā)部');
insert into dept3 values('1002','銷售部');
insert into dept3 values('1003','財(cái)務(wù)部');
insert into dept3 values('1004','人事部');
-- 給emp3表添加數(shù)據(jù)
insert into emp3 values('1','喬峰',20, '1001');
insert into emp3 values('2','段譽(yù)',21, '1001');
insert into emp3 values('3','虛竹',23, '1001');
insert into emp3 values('4','阿紫',18, '1001');
insert into emp3 values('5','掃地僧',85, '1002');
insert into emp3 values('6','李秋水',33, '1002');
insert into emp3 values('7','鳩摩智',50, '1002');
insert into emp3 values('8','天山童姥',60, '1003');
insert into emp3 values('9','慕容博',58, '1003');
insert into emp3 values('10','丁春秋',71, '1005');
交叉連接查詢
MySQL交叉連接查詢(Cross
Join)是一種用于從兩個(gè)或多個(gè)表中返回所有可能的組合的查詢方式。它會(huì)返回左邊表的每一行與右邊表的每一行的所有組合,并且不使用任何連接條件。因此,交叉連接查詢會(huì)產(chǎn)生一個(gè)結(jié)果集,其行數(shù)等于左邊表的行數(shù)乘以右邊表的行數(shù)
select * from 表1,表2
交叉連接查詢實(shí)際上就是多個(gè)表之間進(jìn)行 笛卡爾積 。
兩個(gè)分別有m和n條記錄的表進(jìn)行笛卡爾積之后會(huì)出現(xiàn) m*n 條記錄。
select * from dept3,emp3;
但是我們看到笛卡爾積之后的表的數(shù)據(jù)會(huì)發(fā)現(xiàn)有很多不適合的記錄,所以我們還需要對(duì)笛卡爾積生成的表做出篩選。
內(nèi)連接查詢
MySQL內(nèi)連接查詢(Inner Join)是一種用于從兩個(gè)或多個(gè)表中返回滿足連接條件的記錄集的查詢方式。內(nèi)連接基于指定的連接條件,將兩個(gè)表中的行進(jìn)行匹配,并返回匹配的行。
內(nèi)連接是最常用的連接類型,它可以幫助我們?cè)诙鄠€(gè)表之間建立關(guān)聯(lián)關(guān)系,并獲取相關(guān)的數(shù)據(jù)。內(nèi)連接的結(jié)果集只包含匹配的行,因此可以根據(jù)連接條件進(jìn)行數(shù)據(jù)的關(guān)聯(lián)和過(guò)濾,提供更具體和有意義的結(jié)果。
隱式內(nèi)連接:select * from 表A,表B where 條件;
顯式內(nèi)連接:select * from 表A inner join B on 條件;
inner 可省略。
MySQL還支持兩張以上的表進(jìn)行多表操作:select * from 表A join B on 條件 join C on 條件...;
隱式內(nèi)連接
select * from dept3,emp3 where dept3.deptno = emp3.dept_id;
-- 如果兩張表的列相同,可使用 表名.列名 來(lái)區(qū)分
顯式內(nèi)連接
select * from dept3 inner join emp3 on dept3.deptno = emp3.dept_id;
外連接查詢
MySQL外連接(Outer
Join)是一種用于從兩個(gè)或多個(gè)表中返回滿足連接條件以及一些或全部不滿足連接條件的記錄的查詢方式。外連接可以幫助我們獲取主表和連接表之間的關(guān)系,并包含未匹配的行。
外連接查詢分為:
- 左外連接查詢
- 右外連接查詢
- 滿外連接查詢
左外連接查詢
MySQL左外連接查詢(Left Outer
Join)是一種通過(guò)從左邊表(主表)返回所有行以及滿足連接條件的右邊表(連接表)的匹配行,來(lái)獲取表之間關(guān)聯(lián)數(shù)據(jù)的查詢方式。左外連接會(huì)保留左邊表中的所有行,即使在右邊表中沒(méi)有匹配的行。
左外連接會(huì)將左邊表的每一行與右邊表的匹配行進(jìn)行連接,并返回匹配的結(jié)果集。如果右邊表中沒(méi)有匹配的行,則返回NULL值。
select * from 表A left outer join 表B on 條件;
select * from dept3 left outer join emp3 on dept3.deptno = emp3.dept_id;
這里因?yàn)槿耸虏繘](méi)有員工,但因?yàn)槭亲笸膺B接,要顯示左表中的所有數(shù)據(jù),所以人事部中的數(shù)據(jù)就用 NULL 填充。
右外連接查詢
MySQL右外連接查詢(Right Outer Join)是一種通過(guò)從右邊表(連接表)返回所有行以及滿足連接條件的左邊表(主表)的匹配行,來(lái)獲取表之間關(guān)聯(lián)數(shù)據(jù)的查詢方式。右外連接會(huì)保留右邊表中的所有行,即使在左邊表中沒(méi)有匹配的行。
右外連接會(huì)將右邊表的每一行與左邊表的匹配行進(jìn)行連接,并返回匹配的結(jié)果集。如果左邊表中沒(méi)有匹配的行,則返回NULL值。
select * from 表A right outer join 表B on 條件;
select * from dept3 right outer join emp3 on dept3.deptno = emp3.dept_id;
1005 沒(méi)有對(duì)應(yīng)的部門(mén),所以使用 NULL 填充。
左外連接可以根據(jù)兩個(gè)表互換位置來(lái)實(shí)現(xiàn)相互之間的轉(zhuǎn)換。
select * from emp3 left outer join dept3 on dept3.deptno = emp3.dept_id;
滿外連接查詢
滿外連接是一種同時(shí)返回左邊表和右邊表中的所有行,以及滿足連接條件的匹配行的查詢方式。它能夠獲取左右兩個(gè)表的全部數(shù)據(jù)并關(guān)聯(lián)它們。
滿外連接實(shí)際上就是將右外連接的數(shù)據(jù)拼接到左外連接數(shù)據(jù)的下面或者是將左外連接的數(shù)據(jù)拼接到右外連接數(shù)據(jù)的下面。
但是MySQL不支持滿外連接 full outer join
,我們可以用 union
來(lái)實(shí)現(xiàn)滿外連接 。并且 union
滿外連接還有兩種方式:左外連接 union 右外連接;
去重滿外連接 ,左外連接 union all 右外連接;
不去重滿外連接。
去重滿外連接
select * from dept3 left outer join emp3 on dept3.deptno = emp3.dept_id
union
select * from dept3 right outer join emp3 on dept3.deptno = emp3.dept_id;
不去重滿外連接
select * from dept3 left outer join emp3 on dept3.deptno = emp3.dept_id
union all
select * from dept3 right outer join emp3 on dept3.deptno = emp3.dept_id;
子查詢
MySQL子查詢(Subquery)是指在一個(gè)SQL查詢中嵌套另一個(gè)完整的SQL查詢。子查詢可以像普通的查詢一樣包含SELECT、FROM、WHERE等子句,并且可以返回一個(gè)結(jié)果集,這個(gè)結(jié)果集可以在外部查詢中直接使用。
子查詢通常用于將復(fù)雜的查詢分解為更小的、可管理的查詢塊,并通過(guò)嵌套來(lái)達(dá)到更靈活和精確的查詢目的。它可以嵌套在SELECT、FROM、WHERE等子句中,用于過(guò)濾、排序、計(jì)算和聯(lián)合數(shù)據(jù)。
子查詢可以返回的數(shù)據(jù)類型分為四種:
- 單列單行:返回的是一個(gè)具體列的內(nèi)容,可以理解為一個(gè)單值數(shù)據(jù)。
- 單行多列:返回一行數(shù)據(jù)中多個(gè)列的內(nèi)容
- 多行多列:返回多行記錄之中同一列的內(nèi)容,相當(dāng)于給出了一個(gè)操作范圍。
- 多行多列:查詢返回的結(jié)果是一張臨時(shí)表。
如果我們需要知道某個(gè)部分有哪些人,我們是不是需要先知道這個(gè)部門(mén)所代表的部門(mén)編號(hào),因?yàn)閱T工信息表中存儲(chǔ)的是部門(mén)編號(hào),知道了部門(mén)編號(hào)之后我們才能找出有哪些人。
-- 查詢銷售部有哪些人
select deptno from dept3 where name = '銷售部';
當(dāng)我們知道了部門(mén)編號(hào)之后我們?cè)僭趩T工表中找出部門(mén)編號(hào)為1002的人的信息。
select ename from emp3 where dept_id = 1002;
因?yàn)?select deptno from dept3 where name = '銷售部';
的結(jié)果為1002,所以我們可以直接把這個(gè)查詢嵌套進(jìn) select ename from emp3 where dept_id = 1002;
中,也就是 select ename from emp3 where dept_id = (select deptno from dept3 where name = '銷售部');
select ename from emp3
where dept_id = (select deptno from dept3 where name = '銷售部'); -- 返回單行單列
查詢研發(fā)部和銷售部人的信息。
select eid,ename from emp3
where dept_id
in (select deptno from dept3 where name in ('研發(fā)部','銷售部'));
-- 查詢研發(fā)部30歲以下的員工信息,包括員工號(hào),員工名字,部門(mén)名字
select eid,ename,name from (select * from emp3 where age < 30) t1
join (select * from dept3 where name = '研發(fā)部') t2
on t1.dept_id = t2.deptno;
因?yàn)樽罱K要求顯示員工號(hào)、員工名字、部門(mén)名字,這些數(shù)據(jù)分別在兩個(gè)表中,所以我們需要將兩個(gè)表聯(lián)合起來(lái),并且需要對(duì)每張表中的數(shù)據(jù)做出判斷。
子查詢關(guān)鍵字
在子查詢中有一些常用的邏輯關(guān)鍵字:
- ALL 關(guān)鍵字
- ANY 關(guān)鍵字
- SOME 關(guān)鍵字
- IN 關(guān)鍵字
- EXISTS 關(guān)鍵字
ALL 關(guān)鍵字
在MySQL中,關(guān)鍵字ALL可以用于子查詢中,用于比較子查詢返回的結(jié)果與外部查詢條件進(jìn)行比較。
關(guān)鍵字ALL與子查詢配合使用時(shí),表示外部查詢條件必須與子查詢返回的所有值進(jìn)行比較,只有當(dāng)外部查詢條件大于或小于子查詢中的所有值時(shí),才被視為滿足條件。
select ... from ... where c > all(查詢語(yǔ)句);
-- 查詢員工表中年齡大于1003部門(mén)所有員工的年齡的信息
select * from emp3 where age > all(select age from emp3 where dept_id = 1003);
-- 查詢不屬于任何部門(mén)的員工的信息
select * from emp3 where dept_id != all(select deptno from dept3);
ANY 和 SOME 關(guān)鍵字
在MySQL中,ANY和SOME關(guān)鍵字可以與子查詢一起使用,用于比較外部查詢條件與子查詢返回的結(jié)果集中的任意一個(gè)值進(jìn)行比較。
這兩個(gè)關(guān)鍵字的作用是類似的,它們都表示外部查詢條件只需與子查詢返回的結(jié)果集中的任意一個(gè)值相匹配即可判斷為滿足條件。
select ... from ... where c > any/some(查詢語(yǔ)句);
-- 查詢年齡大于1003部門(mén)任何一個(gè)員工的員工信息
select * from emp3 where age > any(select age from emp3 where dept_id = 1003);
IN 關(guān)鍵字
IN關(guān)鍵字用于檢查外部查詢條件是否與子查詢結(jié)果集中的任意一個(gè)值相匹配。如果外部查詢條件與子查詢結(jié)果集中的某個(gè)值匹配,則被視為滿足條件。
select ... from ... where c in(查詢語(yǔ)句);
-- 查詢部門(mén)為研發(fā)部和銷售部的員工的信息
select * from emp3
where dept_id
in (select deptno from dept3 where name = '研發(fā)部' or name = '銷售部');
EXISTS 關(guān)鍵字
EXISTS關(guān)鍵字用于判斷子查詢是否有結(jié)果,如果存在結(jié)果,則被視為滿足條件,會(huì)執(zhí)行前面的查詢語(yǔ)句,如果子查詢沒(méi)有結(jié)果,則被視為不滿足條件,不執(zhí)行前面的查詢。
select ... from ... where exists(查詢語(yǔ)句);
假設(shè)我們要查詢年齡大于60歲的員工的信息。
-- 查詢年齡大于60歲的員工信息
select * from emp3 where exists (select * from emp3 where age > 60);
會(huì)發(fā)現(xiàn),這里將所有員工的信息都顯示出來(lái)了,這是為什么呢?因?yàn)樵?EXISTS 后面的子查詢中,查找的對(duì)象是emp3 的整個(gè)表,所以每次的查詢都有結(jié)果,所以emp3中的所有信息都打印了,那么我們應(yīng)該怎么辦呢?
我們可以形象的將MySQL的查詢過(guò)程看作是一條記錄一條記錄的篩選,所以我們可以使用表別名,然后用表別名來(lái)判斷每一條記錄的員工的年齡是否大于60。
-- 查詢年齡大于60歲的員工信息
select * from emp3 t where exists (select * from emp3 where t.age > 60);
使用exists的情況大多也可使用in,但是我們推薦使用exists,因?yàn)镸ySQL底層exists做了優(yōu)化,查詢效率更高。
自關(guān)聯(lián)查詢
MySQL自關(guān)聯(lián)查詢是指在查詢中使用同一個(gè)表進(jìn)行連接操作,創(chuàng)建一個(gè)虛擬的關(guān)聯(lián)。在自關(guān)聯(lián)查詢中,可以將表視為兩個(gè)或多個(gè)不同的表,并在查詢中引用它們。
自關(guān)聯(lián)查詢通常涉及到在查詢中使用表的別名,以便可以引用同一個(gè)表的不同實(shí)例。這樣可以通過(guò)列與自身的比較來(lái)建立關(guān)聯(lián)關(guān)系。
自關(guān)聯(lián)查詢?cè)谔幚砭哂袑蛹?jí)結(jié)構(gòu)、關(guān)系鏈等的數(shù)據(jù)時(shí)非常有用,常見(jiàn)的應(yīng)用場(chǎng)景包括獲取管理層級(jí)關(guān)系、查找相關(guān)的記錄、獲取親屬關(guān)系等。
MySQL自查詢必須得使用別名,否則就會(huì)出現(xiàn)錯(cuò)誤
我們準(zhǔn)備一些自關(guān)聯(lián)用到的數(shù)據(jù)。
create table t_sanguo(
eid int primary key,
ename varchar(20),
manager_id int,
foreign key (manager_id) references t_sanguo (eid));
insert into t_sanguo values(1,'劉協(xié)',NULL),
(2,'劉備',1),
(3,'關(guān)羽',2),
(4,'張飛',2),
(5,'曹操',1),
(6,'許褚',5),
(7,'典韋',1),
(8,'孫權(quán)',1),
(9,'周瑜',8),
(10,'魯肅',8);
我們需要顯示出每個(gè)人對(duì)應(yīng)的上級(jí)信息。
select t1.ename,t2.ename manager
from t_sanguo t1 join t_sanguo t2
on t1.manager_id = t2.eid;
我們還應(yīng)該顯示出劉協(xié)的上級(jí)信息,所以我們使用左外連接。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-623696.html
select t1.ename,t2.ename manager
from t_sanguo t1 left join t_sanguo t2
on t1.manager_id = t2.eid;
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-623696.html
到了這里,關(guān)于MySQL數(shù)據(jù)庫(kù)——多表操作的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!