?前言:
多表查詢是指在一個(gè)SQL語句中使用多個(gè)表進(jìn)行數(shù)據(jù)查詢和操作。多表查詢可以對數(shù)據(jù)表之間的關(guān)系進(jìn)行查詢,例如可以通過連接多個(gè)表來獲取更完整的數(shù)據(jù)信息。關(guān)于單表查詢我們也介紹過,已經(jīng)整理成文章發(fā)布:【MySQL數(shù)據(jù)庫 | 第九篇】DQL操作_我是一盤牛肉的博客-CSDN博客
目錄
?前言:
?多表關(guān)系:
1.一對多:
2.多對多:
?3.一對一:
?多表查詢:
?多表查詢的分類:
連接查詢:
? ? ? ? 內(nèi)連接:
? ? ? ? ?外連接:
? ? ? ? ?自連接:
聯(lián)合查詢:
子查詢:
?總結(jié):
?多表關(guān)系:
- 一對多
- 多對多
- 一對一
1.一對多:
實(shí)例:部門與員工之間的關(guān)系,一個(gè)部門對應(yīng)多個(gè)員工,一個(gè)員工對應(yīng)一個(gè)部門。
實(shí)現(xiàn):在多的一方建立外鍵,指向一的一方的主鍵。
圖解:
2.多對多:
實(shí)例:學(xué)生與課程之間的關(guān)系,一個(gè)學(xué)生可以選多門課,一們課也可以讓多個(gè)學(xué)生選擇。
實(shí)現(xiàn):建立中間第三張表,中間至少包含兩個(gè)外鍵,分別關(guān)聯(lián)兩方主鍵
圖解:?實(shí)例:
以多對多的關(guān)系實(shí)現(xiàn)學(xué)生與課程之間的關(guān)系
學(xué)生表:
?課表:
?學(xué)生課程關(guān)系表:
我們把studentid和courseid都設(shè)置稱為兩個(gè)外鍵,分別連接給課表和學(xué)生表。這樣我們就得到了一個(gè)多對多的關(guān)系。
我們可以通過datagrip自帶的視圖工具來更加直觀的圖:
?3.一對一:
實(shí)例:用戶與用戶詳情之間的關(guān)系
關(guān)系:一對一的關(guān)系多用于單表的拆分。
實(shí)現(xiàn):在任意一方加入外鍵,關(guān)聯(lián)另一方的主鍵,并且設(shè)置外鍵是唯一的。
?拆分后:
我們可以在datagrip提供的可視化工具中查看用戶基本信息表和用戶教育信息表的關(guān)系:
?多表查詢:
多表查詢是指在一個(gè)SQL語句中使用多個(gè)表進(jìn)行數(shù)據(jù)查詢和操作。多表查詢可以對數(shù)據(jù)表之間的關(guān)系進(jìn)行查詢,例如可以通過連接多個(gè)表來獲取更完整的數(shù)據(jù)信息。
為了方便演示我們先插入兩張表:dept表和emp表
dept表:
?emp表:
?如果只是直接的兩張表一起查詢:
select *from emp ,dept;
?查詢結(jié)果:
?我們發(fā)現(xiàn)這樣查詢太浪費(fèi)時(shí)間了,因?yàn)檫@是把每一個(gè)人對這個(gè)六個(gè)職位都進(jìn)行一次匹配,這樣確實(shí)不利于我們直接進(jìn)行觀察,這種(A中的每一個(gè)元素都要和B中的元素組合)現(xiàn)象叫做笛卡爾積現(xiàn)象。
而我們在實(shí)際多表查詢的時(shí)候要消除這種多余的笛卡爾積現(xiàn)象,讓數(shù)據(jù)以最直觀,最清晰的方式呈現(xiàn)出來。
?正確的思路應(yīng)該是我們加上一個(gè)判斷條件:只有empt表中人員職位id等于dept職位id的時(shí)候,再進(jìn)行輸出。
代碼:
select * from emp,dept where dept_id=dept.id;
?結(jié)果:
此時(shí)我們就成功的消除了多余的笛卡爾積。
?多表查詢的分類:
連接查詢:
? ? ? ? 內(nèi)連接:
????????????????????????相當(dāng)于查詢A,B交集部分?jǐn)?shù)據(jù)。
? ? ? ? ?外連接:
? ? ? ? ? ? ? ? ? ? ? ?左外連接:查詢左表的所有數(shù)據(jù),以及兩張表的交集數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? ? ?右外連接:查詢右表的所有數(shù)據(jù),以及兩張表的交集數(shù)據(jù)
? ? ? ? ?自連接:
? ? ? ? ? ? ? ? ? ? ? ? 當(dāng)前表與自身的連接查詢,自連接必須使用表別名
聯(lián)合查詢:
? ? ? ? ? ? ? ? ? ? ? ? 把多次查詢的結(jié)果合并起來,形成一個(gè)新的查詢結(jié)果
子查詢:
? ? ? ? ? ?一個(gè)SQL語句中嵌套另一個(gè)SQL語句,嵌套的SQL語句被稱作子查詢。
內(nèi)連接:
1.隱式內(nèi)連接:
SELECT 字段列表 FROM 表1,表2,WHERE 條件;
2.顯式內(nèi)連接:
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 連接條件;
案例:
1.查詢每一個(gè)員工的姓名和關(guān)聯(lián)部門的名稱(隱式內(nèi)連接)
select emp.name,dept.name from emp,dept where emp.dept_id=dept.id;
結(jié)果:
?2.查詢每一個(gè)員工的姓名和關(guān)聯(lián)部門的名稱(顯式內(nèi)連接)
select emp.name,dept.name from emp join dept on emp.dept_id = dept.id;
結(jié)果:
外連接:
左外連接:
select 字段名 from 表1 left [outer] join 表2 on 條件;
右外連接:
select 字段名 from 表1 right [outer] join 表2 on 條件;
我們認(rèn)為表1是左表,表2是右表:
圖解:
?
?案例:
1.查詢emp中的所有信息以及其人員對應(yīng)的部門信息(左外連接)
select emp.* ,d.name from emp left join dept d on d.id = emp.dept_id;
結(jié)果
?2.查詢dept表的所有數(shù)據(jù)和對應(yīng)的員工名稱(右外連接)
select dept.*,e.name from dept right join emp e on dept.id = e.dept_id;
結(jié)果:
自連接:
select 字段列表 from 表A 別名A join 表A 別名B on 條件;
自連接查詢可以是內(nèi)連接查詢,也可以是外連接查詢。
案例
1.查詢員工以及其所屬領(lǐng)導(dǎo)的名字(內(nèi)連接):
select a.name ,b.name from emp a,emp b where a.managerid=b.id;
?結(jié)果:(我們可以看出來此處沒有老板的金庸并沒有顯示出來,因?yàn)樗⒉粚儆趦蓮埍淼慕患?img src="https://imgs.yssmx.com/Uploads/2023/06/475302-21.png" alt="【MySQL數(shù)據(jù)庫 | 第十三篇】多表查詢" referrerpolicy="no-referrer" />
?2.查詢員工以及其所屬領(lǐng)導(dǎo)的名字(外連接)即員工沒有領(lǐng)導(dǎo)也要包含進(jìn)來:
select a.name,d.name from emp a left join emp d on a.managerid=d.id;
結(jié)果:(此時(shí)沒有老板的金庸也被打印出來)
聯(lián)合查詢:
SELECT 字段列表 FROM 表A....
UNION [ALL]
SELECT 字段列表 FROM 表B....
? ALL關(guān)鍵字決定是否去重,如果不想去重就寫ALL。?
案例:
1.將薪資大于5000的員工和年齡大于50歲的員工全部查詢出來
select name from emp where emp.salary>5000
union
select name from emp where emp.age>50;
結(jié)果:
?注意點(diǎn):對于聯(lián)合查詢來講,合并的兩個(gè)查詢字段必須類型一致,列數(shù)一致。
子查詢:
SELECT *FROM T1 WHERE COLUMN1 =(SELECT COLUMN1 FROM T2);
根據(jù)子查詢的種類不同,我們分為
- 標(biāo)量子查詢(子查詢結(jié)果為單個(gè)值)
- 列子查詢(子查詢結(jié)果是一列)
- 行子查詢(子查詢結(jié)果是一行)
- 表子查詢(子查詢的結(jié)果為多行多列)
紅箭頭所指的就是子查詢
標(biāo)量子查詢:
? ? ? ? ? ? ? ? 子查詢返回的結(jié)果是單個(gè)值(字符串,日期,數(shù)字等)
? ? ? ? ? ? ? ? 常用操作符:=? <>? >? >=? ?<? <=
以下這些案例中子查詢返回的都是一個(gè)單個(gè)值:id,entrydate,因此叫做標(biāo)量子查詢。
案例:
1.查詢‘銷售部’的所有員工信息(先查詢銷售部的編號,再查詢誰的崗位編號符合要求)
select * from emp where dept_id=(select id from dept where name ='銷售部');
結(jié)果:
?2.查詢在'方東白'入職之后的員工信息
select * from emp where entrydate>(select entrydate from emp where name='方東白');
結(jié)果:
?列子查詢:
? ? ? ? ? ? ? ?子查詢返回的結(jié)果是一列(可以是多行),這種子查詢叫做列子查詢
? ? ? ? ? ? ? ?常用操作符:IN? ,? NOT IN? ,? ?ANY? ,? SOME? ,? ALL? ? ? ? ?
?案例:
1.查詢 銷售部 和 市場部 的所有員工信息
select * from emp where dept_id in (select id from dept where name ='銷售部'or name ='市場部');
結(jié)果:
?
?2.查詢比財(cái)務(wù)部所有人工資都高的人員信息
select * from emp where salary>all (select salary from emp where dept_id = (select id from dept where name ='財(cái)務(wù)部'));
結(jié)果:
?行子查詢:
? ? ? ? ? ? ? ? 子查詢返回的結(jié)果是一行(可以是多列),這種子查詢就是行子查詢
? ? ? ? ? ? ? ? 常用的操作符:= ,<>? ,IN,NOT IN?
案例:
1.查詢與張無忌薪資和領(lǐng)導(dǎo)相同的員工信息
select * from emp where (salary,managerid)=(select salary,managerid from emp where name ='張無忌')
?結(jié)果:
?表子查詢:
? ? ? ? ? ? ? ? 子查詢的返回結(jié)果是多行多列,這種子查詢結(jié)果就叫做表子查詢
? ? ? ? ? ? ? ? 最常用的操作符:IN
案例:
1.查詢與鹿杖客,宋遠(yuǎn)橋職位和薪資相同的員工信息:
select * from emp where (job,salary) in (select job,salary from emp where name='鹿杖客' or name ='宋遠(yuǎn)橋');
結(jié)果:
?總結(jié):
多表查詢是指在一個(gè)SQL語句中同時(shí)操作多個(gè)表格,并通過對不同表格之間的關(guān)聯(lián)進(jìn)行查詢,來獲得更豐富和更準(zhǔn)確的數(shù)據(jù)。多表查詢的常用方式有內(nèi)連接、左連接、右連接和全連接。多表查詢在實(shí)際操作中應(yīng)用廣泛,能夠滿足復(fù)雜的數(shù)據(jù)查詢和處理需求,同時(shí)也能夠提高數(shù)據(jù)庫的查詢效率和性能。
今天的內(nèi)容到這里就結(jié)束了,感謝大家的閱讀。
如果我的內(nèi)容對你有幫助,請點(diǎn)贊,評論,收藏。創(chuàng)作不易,大家的支持就是我堅(jiān)持下去的動力!文章來源:http://www.zghlxwxcb.cn/news/detail-475302.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-475302.html
到了這里,關(guān)于【MySQL數(shù)據(jù)庫 | 第十三篇】多表查詢的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!