数据库高级——多表查询
多表查詢(xún)
多表查詢(xún)有如下幾種:
2.1. 內(nèi)連接:inner join on
2.2. 外連接:outer join on
– 左外連接:left outer join
– 右外連接:right outer join
2.3.自然連接:natural join
1、合并結(jié)果集
作用:合并結(jié)果集就是把兩個(gè)select語(yǔ)句的查詢(xún)結(jié)果合并到一起。
合并結(jié)果集有兩種方式:
- union:去除重復(fù)記錄
例如:select * from table1 union select * from table2;
- union all :不去除重復(fù)記錄
例如:select * from table1 union all select * from table2;
注意:被合并的兩個(gè)結(jié)果,列數(shù)、列的類(lèi)型必須一致。
2、連接查詢(xún)
連接查詢(xún)就是求出多個(gè)表的乘積,例如 t1 連接 t2,那么查詢(xún)出的結(jié)果就是t1 * t2
觀察下面例子:
連接查詢(xún)會(huì)產(chǎn)生笛卡爾積,假設(shè)集合A={a,b},集合B={0,1,2},則兩個(gè)集合的笛卡爾積為{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以擴(kuò)展到多個(gè)集合的情況。
多表查詢(xún)產(chǎn)生這樣的結(jié)果并不是我們想要的,那么該如何去除重復(fù)的,不想要的記錄呢。
答案是通過(guò)條件過(guò)濾。
通常要查詢(xún)的多個(gè)表之間都存在關(guān)聯(lián)關(guān)系,那么就通過(guò)關(guān)聯(lián)關(guān)系去除笛卡爾積。
示例:
現(xiàn)在有兩張表,一張部門(mén)表,一張員工表:
如果使用連接查詢(xún),那么結(jié)果就是一大堆重復(fù)多余的記錄,如下圖:
這個(gè)時(shí)候,使用主外鍵關(guān)系作為條件去除無(wú)用記錄
select * from dept1,emp1 where dept1.deptno=emp1.deptno;
上面會(huì)把兩張表的所有列都查詢(xún)出來(lái),如果不需要那么多列,也可以指定列名查詢(xún)。
select emp1.empno,emp1.ename,emp1.sal,emp1.comm,dept1.dname from dept1,emp1 where dept1.deptno=emp1.deptno;
2.1、內(nèi)連接
上面的連接語(yǔ)句就是內(nèi)連接,但它不是SQL標(biāo)準(zhǔn)中的查詢(xún)方式,可以理解為方言。
語(yǔ)法:
select 列名
from 表1
inner join 表2
on 表1.列名=表2.列名;
等價(jià)于:
select 列名
from 表1,表2
where 表1.列名=表2.列名;
注意:
三表聯(lián)查:
語(yǔ)法:
select 列名 from 表1
inner join 表2 on 表1.列名=表2.列名
inner join 表3 on 表1或表2.列名=表3.列名;
等價(jià)于:
select 列名 from 表1,表2,表3
where 表1.列名=表2.列名 and 表1或表2.列名=表3.列名
SQL標(biāo)準(zhǔn)的內(nèi)連接為:
SELECT * FROM emp e INNER JOIN dept d ON e.deptno=d.deptno;內(nèi)連接的特點(diǎn):查詢(xún)結(jié)果必須滿足條件。
案例:
現(xiàn)在有三張表:學(xué)生(student2)表、科目(subject2)表、成績(jī)(score2)表。
需求:
1.顯示出花兒的考試成績(jī)以及對(duì)應(yīng)科目
2.顯示出所有考試學(xué)生的信息
3.查詢(xún)出mysql的考試信息
4.查詢(xún)出考試學(xué)員的總分
5.查詢(xún)每科的平均分
2.2、外連接
外連接包括左外連接和右外連接。
外連接特點(diǎn):查詢(xún)的結(jié)果存在不滿足條件的可能。
外聯(lián)查詢(xún):
左外聯(lián):select 列名 from 主表 left join 次表 on 主表.列名=次表.列名;
右外聯(lián):selecr 列名 from 次表 right join 主表 on 主表.列名=次表.列名;
使用場(chǎng)景:在開(kāi)發(fā)過(guò)程中,用得較少,一般作為子查詢(xún)的語(yǔ)句使用。
左外連接:
左連接是先查詢(xún)出左表,然后查詢(xún)出右表,右表中滿足條件的顯示出來(lái),不滿足條件的顯示NULL。
例如在emp1表的基礎(chǔ)上增添一條“麻子”的記錄,其中部門(mén)編號(hào)為50,而dept1表中不存在部門(mén)為50的記錄,所以“麻子”這條記錄不滿足語(yǔ)句中的條件,但是在左連接中,因?yàn)閑mp1是左表(主表),所以左表的記錄都會(huì)查詢(xún)出來(lái),但是右表部分顯示NULL。如下圖所示:
右外連接:
右連接就是先把右表中所有記錄都查詢(xún)出來(lái),然后左表滿足條件的顯示,不滿足顯示NULL。
例如在dept1表中60部門(mén)并不存在員工,但在右連接中,如果dept1為右表,那么還是會(huì)查出60后勤部,但相應(yīng)的員工信息為NULL。如下圖所示:
連接查詢(xún)心得:
連接不限與兩張表,連接查詢(xún)也可以是三張、四張…N張的連接查詢(xún)。通常查詢(xún)不可能需要整個(gè)笛卡爾積,而只是需要其中一部分,那么這時(shí)就需要使用條件來(lái)去除不需要的記錄。這個(gè)條件大多數(shù)情況下都是使用主外鍵關(guān)系去除。
兩張表的連接查詢(xún)一定有一個(gè)主外鍵關(guān)系,三張表的連接查詢(xún)就一定有兩個(gè)主外鍵關(guān)系。
2.3、自然連接
自然連接(NATURAL INNER JOIN):自然連接是一種特殊的等值連接,他要求兩個(gè)關(guān)系表中進(jìn)行連接的必須是相同的屬性列(名字相同),無(wú)須添加連接條件,并且在結(jié)果中消除重復(fù)的屬性列。
語(yǔ)句:select * from emp1 natural join dept1;
示例:在下面的圖中,可以看到dept1表中的deptno列被消去了。
3、子查詢(xún)
子查詢(xún):一個(gè)select語(yǔ)句中包含另一個(gè)完整的select語(yǔ)句。
子查詢(xún)就是嵌套查詢(xún),即SELECT中包含SELECT,如果一條語(yǔ)句中存在兩個(gè),或兩個(gè)以上SELECT,那么就是子查詢(xún)語(yǔ)句了。
子查詢(xún)出現(xiàn)的位置:
- where后,作為條件中被查詢(xún)的一條件的一部分;
- from后,作表;
當(dāng)子查詢(xún)出現(xiàn)在where 后作為條件時(shí),還可以使用如下關(guān)鍵字:
- any(任一)
- all(全部)
子查詢(xún)結(jié)果集的形式:
- 單行單列(用于條件)
- 單行多列(用于條件)
- 多行單列(用于條件)
- 多行多列(用于表)
示例:
工資高于JONES的員工
分析:
查詢(xún)條件:工資>JONES工資,其中JONES工資需要一條子查詢(xún)。
第一步:查詢(xún)JONES的工資
select sal from emp where ename='JONES';
第二步:查詢(xún)高于JONES工資的員工
select * from emp where sal>(第一步結(jié)果);
結(jié)果:
select * from emp where sal>(select sal from emp where ename='JONES);
查詢(xún)與SCOTT同一個(gè)部門(mén)的員工
子查詢(xún)作為條件
子查詢(xún)形式為單行單列
分析:
查詢(xún)條件:部門(mén)=SCOTT的部門(mén)編號(hào),其中SCOTT的部門(mén)編號(hào)需要一條子查詢(xún)。
第一步:查詢(xún)SCOTT的部門(mén)編號(hào)
select deptno from emp where ename='SCOTT';
第二步:查詢(xún)部門(mén)編號(hào)等于SCOTT的部門(mén)編號(hào)的員工
select * from emp where deptno=(select deptno from emp where ename='SCOTT');
工資高于30號(hào)部門(mén)所有人的員工信息
分析:select * from emp where sal>(select max(sal) from emp where deptno=30);
查詢(xún)條件:工資高于30部門(mén)所有人工資,其中30號(hào)部門(mén)所有人工資是子查詢(xún)。高于所有需要使用all關(guān)鍵字。
第一步:查詢(xún)30號(hào)部門(mén)所有人工資
select sal from emp where deptno=30;
第二步:查詢(xún)高于30號(hào)部門(mén)所有人工資的員工信息
select * from emp where sal>all (第一步);
結(jié)果:
select * from emp where sal>all(select sal from emp where deptno=30);
子查詢(xún)作為條件
子查詢(xún)形式為多行單列
當(dāng)子查詢(xún)結(jié)果集形式為多行多列時(shí)可以使用all或any關(guān)鍵字
相關(guān)鏈接:單表查詢(xún)(常用語(yǔ)句)
總結(jié)
以上是生活随笔為你收集整理的数据库高级——多表查询的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: H5实现轮播
- 下一篇: 阿里云mysql数据库日志_阿里云mys