程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> 其他數據庫知識 >> MSSQL >> SQL Join的一些總結(實例)

SQL Join的一些總結(實例)

編輯:MSSQL

SQL Join的一些總結(實例)。本站提示廣大學習愛好者:(SQL Join的一些總結(實例))文章只能為提供參考,不一定能成為您想要的結果。以下是SQL Join的一些總結(實例)正文


1.1.1 摘要
Join是關系型數據庫體系的主要操作之一,SQL Server中包括的經常使用Join:內聯接、外聯接和穿插聯接等。假如我們想在兩個或以上的表獲得個中從一個表中的行與另外一個表中的行婚配的數據,這時候我們應當斟酌應用Join,由於Join詳細聯接表或函數停止查詢的特征

本文將經由過程詳細例子引見SQL中的各類經常使用Join的特征和應用場所:

1.1.2 注釋
起首我們在tempdb平分別界說三個表College、Student和Apply,詳細SQL代碼以下:

USE tempdb

---- If database exists the same name datatable deletes it.
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'College') DROP TABLE College;
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Student') DROP TABLE Student;
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Apply') DROP TABLE Apply;

---- Create Database.
create table College(cName nvarchar(50), state text, enrollment int);
create table Student(sID int, sName nvarchar(50), GPA real, sizeHS int);
create table Apply(sID int, cName nvarchar(50), major nvarchar(50), decision text);


Inner join

內聯接(Inner join)是最經常使用的聯接類型之一,它查詢知足聯接謂詞的數據。

假定我們要查詢請求表Apply中請求黉捨的相干信息,因為Apply表中包括黉捨名字我們其實不能預知,所以我們可以依據cName來內聯接(Inner join)表College和Apply,從而找到Apply表中包括黉捨的信息。

詳細SQL代碼以下:

---- Gets college information from college table
---- bases on college name.
SELECT DISTINCT College.cName, College.enrollment
FROM College INNER JOIN
Apply ON College.cName = Apply.cName

join0

圖1查詢成果
cName state enrollment Stanford CA 15000 Berkeley CA 36000 MIT MA 10000 Cornell NY 21000 Harvard MA 29000表1 College表中的數據

如上圖1所示,我們把Apply表包括的黉捨信息查詢出來了,因為Harvard並沒有被查詢出來,所以我們曉得臨時還沒有先生請求Harvard。

內聯接(Inner join)知足交流律:“A inner join B” 和 “B inner join A” 是相等的。

Outer join
假定我們想看到一切黉捨信息;即便是那些沒有請求的黉捨(如:Harvard),這時候我們可使用內部聯接(Outer join)停止查詢。因為內部聯接保留一個或兩個輸出表的一切行,即便沒法找到婚配聯接謂詞的行。

詳細SQL代碼以下:

---- Gets all college information
SELECT College.cName, College.state, College.enrollment,
Apply.cName, Apply.major, Apply.decision
FROM College LEFT OUTER JOIN

join3

圖3左聯接查詢成果

如上圖3所示:因為在Apply表中並沒有先生請求Harvard,然則我們經由過程左聯接(left outer join)把一切黉捨信息查詢出來了。

因為左聯接(left outer join)發生表College的完整集,而Apply表中婚配的則有值,而不婚配的則以NULL值代替,所以我們曉得Apply表中沒有先生請求Harvard。

經由過程左聯接查詢我們可以獲得College的完整集,假定如今我們既要獲得College的完整集又要獲得Apply的完整集,那末我們可以斟酌應用完全內部聯接(full outer join)。應用完全內部聯接,我們可以查詢一切的黉捨,不論它們能否婚配聯接謂詞:

---- Gets all information from college and apply table.
SELECT College.cName, College.state, College.enrollment,
Apply.cName, Apply.major, Apply.decision
FROM College FULL OUTER JOIN
Apply ON College.cName = Apply.cName

join4

圖3 完全內部聯接查詢成果

如今我們獲得了College和Apply的完整數據集,關於表中婚配的則有值,即便沒有找到婚配cName的則以NULL值代替。

下表顯示每種內部聯接(outer join)婚配時保存數據行的情形:

聯接類型

保存數據行

A left outer join B

all A rows

A right outer join B

all B rows

A full outer join B

all A and B rows


表2 內部聯接保存數據行

完全內部聯接(full outer join)知足交流律:“A full outer join B” 和 “B full outer join A” 是相等的。

Cross join
穿插聯接(cross join)履行兩個表的笛卡爾積(就是把表A和表B的數據停止一個N*M的組合)。也就是說,它婚配一個表與另外一個表中的每行;我們不克不及經由過程應用ON子句在穿插聯接指定謂詞,固然我們可使用WHERE子句來完成雷同的成果,這是穿插聯接根本上是作為一個外部聯接了。

穿插聯接絕對於外部聯接應用率較低,並且兩個年夜表不該該停止穿插聯接,由於這將招致一個異常昂貴的操作和一個異常年夜的成果集。

詳細SQL代碼以下:

---- College Cross join Apply.
SELECT College.cName, College.state, College.enrollment,
Apply.cName, Apply.major, Apply.decision
FROM College
CROSS JOIN Apply

join5
圖4 College表和Apply表的行數

join6

圖5 穿插聯接

如今我們對College和Apply表停止穿插聯接,並且生成數據行動College和Apply表行數的笛卡爾積即5 * 20 = 100。

Cross apply
在SQL Server 2005中供給了Cross apply使表可以和表值函數(table-valued functions TVF‘s)成果停止join查詢。例如,如今我們想經由過程函數的成果值和表Student停止查詢,這時候我們可使用Cross apply停止查詢:

---- Creates a function to get data from Apply base on sID.
CREATE FUNCTION dbo.fn_Apply(@sID int)
RETURNS @Apply TABLE (cName nvarchar(50), major nvarchar(50))
AS
BEGIN
INSERT @Apply SELECT cName, major FROM Apply where [sID] = @sID
RETURN
END

---- Student cross apply function fn_Apply.
SELECT Student.sName, Student.GPA, Student.sizeHS,
cName, major
FROM Student CROSS APPLY dbo.fn_Apply([sID])

我們也能夠應用外部聯接完成和Cross apply雷同的查詢功效,詳細SQL代碼以下:

---- Student INNER JOIN Apply bases on sID.
SELECT Student.sName, Student.GPA, Student.sizeHS,
cName, major
FROM Student INNER JOIN [Apply]
ON Student.sID = [Apply].sID


join7

圖6 Cross apply查詢

Outer apply
在引見Cross apply和Outer join以後,如今讓我們懂得Out apply也就不難了,Outer apply使表可以和表值函數(table-valued functions TVF‘s)成果停止join查詢,找到婚配值則有值,沒有找到婚配值則以NULL表現。

---- Student outer apply function fn_Apply.
SELECT Student.sName, Student.GPA, Student.sizeHS,
cName, major
FROM Student OUTER APPLY dbo.fn_Apply([sID])

join10
圖7 Outer apply查詢

Inner Join和Cross apply的差別

起首我們曉得Inner join是表和表的聯接查詢,而Cross apply是表和表值函數的聯接查詢,在後面Cross apply例子中,我們也能夠經由過程Inner join完成雷同的查詢。

---- Student cross apply function fn_Apply.
SET STATISTICS PROFILE ON
SET STATISTICS TIME ON

SELECT Student.sName, Student.GPA, Student.sizeHS,
cName, major
FROM Student CROSS APPLY dbo.fn_Apply([sID])

SET STATISTICS PROFILE OFF
SET STATISTICS TIME OFF

---- Student INNER JOIN Apply base on sID.
SET STATISTICS PROFILE ON
SET STATISTICS TIME ON

SELECT Student.sName, Student.GPA, Student.sizeHS,
cName, major
FROM Student INNER JOIN [Apply]
ON Student.sID = [Apply].sID

SET STATISTICS PROFILE OFF
SET STATISTICS TIME OFFCross apply

查詢履行時光:

CPU 時光= 0 毫秒,占用時光= 11 毫秒。

Inner join查詢履行時光:

CPU 時光= 0 毫秒,占用時光= 4 毫秒。

join8

圖8 履行籌劃

如圖8所示:Cross apply起首履行TVF(table-valued functions),然後對表Studnet停止全表掃描,接著經由過程遍歷sID查找婚配值。

Inner join對表Student和Apply停止全表掃描,然後經由過程哈希婚配查找婚配的sID值。

經由過程以上的SQL履行時光和履行籌劃,我們能不克不及說Inner join比Cross apply好呢?謎底能否定的,假如表的數據量很年夜,那末Inner join的全表掃描消耗時光和CPU資本就增長了(可經由過程數據量年夜的表停止測試)。

固然年夜多半采取Cross apply完成的查詢,可以經由過程Inner join完成,但Cross apply能夠發生更好的履行籌劃和更佳的機能,由於它可以在聯接履行之前限制聚集參加。

Semi-join和Anti-semi-join

Semi-join從一個表中前往的行與另外一個表中數據行停止不完整聯接查詢(查找到婚配的數據行就前往,不再持續查找)。

Anti-semi-join從一個表中前往的行與另外一個表中數據行停止不完整聯接查詢,然後前往不婚配的數據。

分歧於其他的聯接運算,Semi-join和Anti-semi-join沒有明白的語法來完成,但Semi-join和Anti-semi-join在SQL Server中有多種運用場所。我們可使用EXISTS子來完成Semi-join查詢,Not EXISTS來完成Anti-semi-join。如今讓我們經由過程詳細的例子解釋吧!

假定請求我們找出Apply和Student表中sID婚配的先生信息,這和後面的Inner join查詢成果將一樣,詳細SQL代碼以下:

---- Student Semi-join Apply base on sID.
SELECT Student.sName, Student.GPA, Student.sizeHS
----[Apply].cName, [Apply].major
FROM Student
WHERE exists (
SELECT *
from [Apply]
where [Apply].sID = Student.sID
)

我們發明經常使用的EXISTS子句,本來是經由過程Left Semi Join完成的,所以說Semi-join在SQL Server中又很多應用場所。


join13

圖9 查詢成果

join12



圖10 履行籌劃

如今請求我們找出還沒有請求黉捨的先生信息,這時候我們連忙反響可使用NOT EXISTS子句來完成該查詢,詳細SQL代碼以下:

---- Gets student still not apply for school.
SELECT Student.sID, Student.sName, Student.GPA, Student.sizeHS
----[Apply].cName, [Apply].major
FROM Student
WHERE NOT EXISTS (
SELECT *
FROM [Apply]
WHERE [Apply].sID = Student.sID
)

其實,我們經常使用的NOT EXISTS子句的完成是經由過程Anti-semi-join,經由過程履行籌劃我們發明在查找婚配sID時,SQL應用 Left Anti Semi Join停止查詢。

join14

圖11 查詢成果

join15


圖12 履行籌劃

1.1.3 總結
本文引見了SQL中經常使用了聯接查詢方法:Inner join、Outer join、Cross join和Cross apply的應用場所和特征。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved