日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL Server【三】连接查询

發(fā)布時間:2023/11/30 数据库 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL Server【三】连接查询 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

將兩個表或者兩個以上的表以一定的連接條件連接起來,從中檢索出滿足條件的數(shù)據(jù)。

內(nèi)連接

使用inner join,inner可以省略

-- 查詢員工的姓名和部門名稱 select "E".ename as "員工姓名", "D".dname as "部門名稱"from emp "E"join dept "D"on "E".deptno = "D".deptno

select … from A, B

假設(shè)A表有xxx行,則行可以表示為集合(a1,a2,...,ax)(a_1,a_2,...,a_x)(a1?,a2?,...,ax?)
假設(shè)B表有yyy行,則行可以表示為集合(b1,b2,...,by)(b_1,b_2,...,b_y)(b1?,b2?,...,by?)
則select ... from A,B就是將兩個表的行進行笛卡爾成績,并將兩個行進行合并得到(a1+b1,a1+b2,...,a2+b1,a2+b2,...)(a_1+b_1,a_1+b_2,...,a_2+b_1,a_2+b_2,...)(a1?+b1?,a1?+b2?,...,a2?+b1?,a2?+b2?,...),因此總共的行數(shù)是x?yx*yx?y,總共的列數(shù)是兩個表列數(shù)相加

即把A表的每一條記錄都和B表的每一條記錄組合在一起

select … from A,B where …

對上面的表用where的條件進行過濾

select E.ename as "員工姓名", D.dname as "部門名稱"from emp as "E", dept as "D"where E.deptno = D.deptno

select … from A join B on …

join是連接的意思 on 表示連接條件
如果使用join就必須使用on

select * from empjoin depton 1=1 --70*11select emp.ename as '員工姓名', dept.deptno as '部門編號'from empjoin depton 1 = 1 --70*2select emp.ename as '員工姓名', dept.deptno as '部門編號'from empjoin depton emp.deptno=dept.deptno --14*2select E.ename as '員工姓名', D.deptno as '部門編號'from emp as "E"join dept as "D"on E.deptno=D.deptno --14*2 select *from emp as "E"join dept as "D"on 1 =1 select *from dept as "D"join emp as "E"on 1 =1 order by D.deptnoselect * from dept,emp where dept.deptno = emp.deptno --實際中發(fā)現(xiàn)無論將哪個表放在前面,總是用行數(shù)少的表匹配行數(shù)多的

from和join后面可以使用別名,如果在這里使用別名,其他的地方也都必須使用別名。區(qū)別于select后面的別名不能在其他地方使用,我認(rèn)為根本原因在于語句的執(zhí)行順序

實際上和select ... from A,B where ...等價,推薦使用join on

使用join on可以再使用where對得到的數(shù)據(jù)過濾,從而實現(xiàn)不同的分工

混合使用

select * from emp as "E", dept as "D" where E.deptno=D.deptno and E.sal>2000 --等價于下面的寫法,下面的寫法更加清晰 select * from emp as "E"join dept as "D"on E.deptno = D.deptnowhere E.sal > 2000--求出工資大于2000的員工的姓名 部門編號 薪水 薪水等級 select emp.ename as "員工姓名", dept.dname as "部門名稱", emp.sal as "薪水", SALGRADE.GRADE as "薪水等級"from emp,dept,SALGRADEwhere emp.deptno=dept.deptno and emp.sal>2000 and emp.sal >= SALGRADE.LOSAL and emp.sal <=SALGRADE.HISALselect emp.ename as "員工姓名", dept.dname as "部門名稱", emp.sal as "薪水", SALGRADE.GRADE as "薪水等級"from empjoin depton emp.deptno=dept.deptnojoin SALGRADEon emp.sal>=SALGRADE.LOSAL and emp.sal<=SALGRADE.HISALwhere emp.sal>2000

我們也可以把查詢的表當(dāng)作一個表,進行子查詢

-- 輸出部門名稱,該部門所有員工的平均工資 平均工資等級select dept.dname as "部門名稱", tmp.avg_sal as "平均工資", SALGRADE.GRADE as "平均工資等級"from(select emp.deptno as "dept_no", AVG(emp.sal) as "avg_sal"from empgroup by emp.deptno) "tmp"join depton dept.deptno = tmp.dept_nojoin SALGRADEon tmp.avg_sal between SALGRADE.LOSAL and SALGRADE.HISAL

語句順序

SELECT ...INTOFROMJOINONWHEREGROUP BYHAVINGORDER BY -- 輸出3個姓名中不含有O的工資最高的員工的姓名、工資、工資等級、部門名稱select top 3 emp.ename as "員工姓名", emp.sal as "員工工資", SALGRADE.GRADE as "工資等級", dept.dname as "部門名稱"from empjoin depton emp.deptno=dept.deptnojoin SALGRADEon emp.sal >= SALGRADE.LOSAL and emp.sal <= SALGRADE.HISALwhere emp.ename not like '%O%'order by emp.sal desc

當(dāng)null和not in在一起的時候需要注意。如果表中有null,則使用not in的時候返回的總為空。

這與SQL的比較機制有關(guān)。在SQL中比較結(jié)果分為true``false``null,只有結(jié)果為true的時候系統(tǒng)才認(rèn)為匹配成功并返回記錄,in的本質(zhì)是等于的or,not in的本質(zhì)是不等于的and。

比較結(jié)果and nullor null
truenulltrue
falsefalsenull
nullnullnull

當(dāng)使用in的時候因為是or進行連接,所以可以正常返回true,在not in的時候是and連接,因此返回總為null,因此返回為空。

詳細原因可以看這篇文章:傳送門。為了解決這個問題我們可以使用is [not] null和isnull()函數(shù)組合判斷

--求出emp表中所有領(lǐng)導(dǎo)的姓名select distinct E1.ename as "領(lǐng)導(dǎo)姓名"from emp "E1"join emp "E2"on E1.EMPNO = E2.mgrselect emp.ename as "領(lǐng)導(dǎo)姓名"from empwhere emp.EMPNO in (select distinct mgr from emp)--輸出所有非領(lǐng)導(dǎo)的信息select *from empwhere emp.EMPNO not in (select distinct mgr from emp where mgr is not null) --求出平均薪水最高的部門的名稱和部門平均工資select dept.dname as "部門名稱", tmp.avg_sal as "平均工資"from (select top 1 emp.deptno as "dept_no", AVG(emp.sal) as avg_salfrom empgroup by emp.deptnoorder by AVG(emp.sal) desc) "tmp"join depton tmp.dept_no=dept.deptno

當(dāng)子查詢的值只有一個的時候可以將子查詢放在表達式中

--工資大于 所有員工中工資最低的人中的工資 的人中 --前三個人的姓名 工資 部門編號 部門名稱 工資等級 select top 3 emp.ename as "姓名", emp.sal as "工資", emp.deptno as "部門編號", dept.dname as "部門名稱", SALGRADE.GRADE as "工資等級"from empjoin (select MIN(sal) as "min_sal" from emp) as "tmp"on emp.sal > tmp.min_saljoin dept on emp.deptno = dept.deptnojoin SALGRADEon emp.sal between SALGRADE.LOSAL and SALGRADE.HISALorder by emp.sal select top 3 tmp.ename as "姓名", tmp.sal as "工資", tmp.deptno as "部門編號", dept.dname as "部門名稱", SALGRADE.GRADE as "工資等級"from ( select ename,sal,deptno from emp where sal > (select MIN(sal) as "min_sal" from emp)) as "tmp"join dept on tmp.deptno = dept.deptnojoin SALGRADEon tmp.sal between SALGRADE.LOSAL and SALGRADE.HISALorder by tmp.sal --把工資大于1500的所有員工按部門分組, --按升序輸出最后兩個平均工資小于3000的部門名稱,人數(shù),平均工資,平均工資水平 select dept.dname as "部門名稱", tmp.number as "部門人數(shù)", tmp.avg_sal as "平均工資", SALGRADE.GRADE as "平均給工資水平"from(select top 2 deptno as "dept_no", COUNT(*) as "number", AVG(sal) as "avg_sal"from emp where sal>1500 group by deptnohaving AVG(sal)<3000order by AVG(sal) desc) "tmp"join depton tmp.dept_no=dept.deptnojoin SALGRADEon tmp.avg_sal between SALGRADE.LOSAL and SALGRADE.HISALorder by tmp.avg_sal

order by的順序應(yīng)該在最后,因此可以用別名。group by和having都不可以用別名

外連接

不但返回滿足條件的所有記錄,而且會返回部門不滿足條件的記錄。

左外連接

select * from empleft join depton emp.deptno=dept.deptno
  • 用左表的一行分別和右表的所有行進行連接,如果沒有匹配的行,則一起輸出,如果右表有多行匹配,則結(jié)果輸出多行。如果沒有匹配行,則結(jié)果只輸出一行,該輸出左邊為左表的一行的內(nèi)容,右邊全部輸出null
  • 因為右邊很可能出現(xiàn)有多行和左表的某一行匹配,所以左連接產(chǎn)生的結(jié)果集的行數(shù)很可能大于左邊表的行數(shù)
select * from deptleft join empon dept.deptno=emp.deptno --16行

返回一個事物和該事物的相關(guān)信息,如果沒有相關(guān)信息,就輸出空

右外連接

同左外連接

完全連接

full join

  • 兩個表中匹配的所有行記錄
  • 左表中那些在右表找不到匹配的行的記錄,右邊為NULL
  • 右表中那些在左表找不到匹配的行的記錄,左邊為NULL

交叉連接

cross join等價于join on 1=1,后面不用加on

自連接

一張表和自己連接起來,注意連接自己的時候需要標(biāo)明是哪一張表中的字段

--求薪水最高的員工的信息select *from empwhere sal = (select MAX(sal) from emp)-- 不準(zhǔn)用聚合函數(shù),求薪水最高的員工的信息 select *from empjoin (select top 1 EMPNO from emp order by sal desc) "tmp"on emp.EMPNO=tmp.EMPNOselect *from empwhere sal not in (select distinct E1.salfrom emp as "E1"join emp as "E2"on E1.sal < E2.sal)

聯(lián)合

縱向連接表中的數(shù)據(jù),即添加一行

--輸出每個員工的姓名,工資,上司的姓名select E1.ename as "姓名", E1.sal as "工資", E2.ename as "上司"from emp as "E1"left join emp as "E2" --用左連接的原因是有一個沒有上司on E1.mgr = E2.EMPNO--或者使用聯(lián)合select E1.ename as "姓名", E1.sal as "工資", E2.ename as "上司"from emp as "E1"join emp as "E2"on E1.mgr = E2.EMPNO union select ename, sal, 'BOSS' from emp where mgr is null

注意:

  • select子句輸出列數(shù)相等
  • 數(shù)據(jù)類型也相同,至少是兼容的

分頁查詢

總結(jié)

以上是生活随笔為你收集整理的SQL Server【三】连接查询的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。