sql server關(guān)鍵字詳解大全(圖文)
下面把sqlserver中cross apply和outer apply關(guān)鍵字具體介紹展示如下:
1.CROSS APPLY 和OUTER APPLY
MSDN解釋如下(個人理解不是很清晰):
使用 APPLY 運算符可以為實現(xiàn)查詢操作的外部表表達式返回的每個行調(diào)用表值函數(shù)。表值函數(shù)作為右輸入,外部表表達式作為左輸入。
通過對右輸入求值來獲得左輸入每一行的計算結(jié)果,生成的行被組合起來作為最終輸出。
APPLY 運算符生成的列的列表是左輸入中的列集,后跟右輸入返回的列的列表。
APPLY 有兩種形式:
CROSS APPLY 和 OUTER APPLY。
CROSS APPLY 僅返回外部表中通過表值函數(shù)生成結(jié)果集的行。
OUTER APPLY 既返回生成結(jié)果集的行,也返回不生成結(jié)果集的行,其中表值函數(shù)生成的列中的值為 NULL。
網(wǎng)上搜集的解釋如下(個人感覺好理解):
SQL Server數(shù)據(jù)庫操作中,在2005以上的版本新增加了一個APPLY表運算符的功能。新增的APPLY表運算符把右表表達式應(yīng)用到左表表達式中的每一行。
它不像JOIN那樣先計算哪個表表達式都可以,APPLY必須先邏輯地計算左表達式。這種計算輸入的邏輯順序允許把右表達式關(guān)聯(lián)到左表表達式。
APPLY有兩種形式,一個是OUTER APPLY,一個是CROSS APPLY,區(qū)別在于指定OUTER,意味著結(jié)果集中將包含使右表表達式為空的左表表達式中的行,而指定CROSS,則相反,結(jié)果集中不包含使右表表達式為空的左表表達式中的行。
注意:若要使用 APPLY,數(shù)據(jù)庫兼容級別必須為 90。
下面我們做個例子:
比如有個類別表(Category)內(nèi)容如下:

還有個類別明細表(CategoryDetail)內(nèi)容如下:

下面我們來看看OUTER APPLY 的查詢結(jié)果:
SELECT *
FROM dbo.Category a
OUTER APPLY ( SELECT *
FROM dbo.CategoryDetail b
WHERE b.CategoryId = a.Id
) AS c ;

由上圖可看出OUTER APPLY把左表中的信息查出后把右表中的信息也關(guān)聯(lián)出來了,當(dāng)然當(dāng)右表的信息為空(NULL)時,OUTER APPLY也會在結(jié)果集中顯示出來.
接下來我們看下CROSS APPLY的查詢結(jié)果:
SELECT *
FROM dbo.Category a
CROSS APPLY ( SELECT *
FROM dbo.CategoryDetail b
WHERE b.CategoryId = a.Id
) AS c ;

根據(jù)這圖和上面的比較可看出,這個返回結(jié)果只有兩個,Category 表中的Tiger的信息沒有帶出來,因為在CategoryDetail 表中沒有對應(yīng)的明細.
由以上信息可得出,OUTER APPLY 就相當(dāng)于數(shù)學(xué)中的并集,而CROSS APPLY相當(dāng)于數(shù)學(xué)中的交集,關(guān)于交集與并集的介紹如下:
并集為下圖中的所有紅色部分,即為A和B的全部:

交集為下圖中的紅色部分,也就是A和B相交的部分:

2.OUTER APPLY 和LEFT JOIN
LEFT JOIN 關(guān)鍵字會從左表 (Category) 那里返回所有的行,即使在右表 (CategoryDetail) 中沒有匹配的行。
注釋:在某些數(shù)據(jù)庫中, LEFT JOIN 稱為 LEFT OUTER JOIN。
下面我們來看看LEFT JOIN 的查詢結(jié)果(還是1.CROSS APPLY 和 OUTER APPLY中的例子):
SELECT * FROM dbo.Category a LEFT JOIN dbo.CategoryDetail b ON b.CategoryId = a.Id ;

LEFT JOIN 關(guān)鍵字會從左表 (Category) 那里返回所有的行,即使在右表 (CategoryDetail) 中沒有匹配的行。效果和OUTER APPLY 一樣。
OUTER APPLY 和 LEFT JOIN 的主要區(qū)別為:
一個LEFT JOIN 關(guān)鍵字只能JOIN 一個表,不能解決一個復(fù)雜的SELECT 語句,或者函數(shù)方法等。
一個OUTER APPLY 關(guān)鍵字可以包含一個獨立的復(fù)雜的SELECT 語句,或者其他函數(shù)方法等。
OUTER APPLY 和 LEFT JOIN 性能的區(qū)別:
通過本文總結(jié)可知LEFT JOIN和OUTER APPLY性能比較的總結(jié)可知 LEFT JOIN 要比 OUTER APPLY 性能要快。所以建議能用LEFT JOIN的盡量不要用OUTER APPLY。
附注:
附Category 表和CategoryDetail 表的結(jié)果及插入數(shù)據(jù)的腳本:
CREATE TABLE [dbo].[CategoryDetail]( [Id] [int] IDENTITY(,) NOT NULL, [CategoryId] [int] NULL, [Cry] [varchar]() NULL, CONSTRAINT [PK_CategoryDetail] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO SET IDENTITY_INSERT [dbo].[CategoryDetail] ON INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (, , N'喵') INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (, , N'汪') SET IDENTITY_INSERT [dbo].[CategoryDetail] OFF /****** Object: Table [dbo].[Category] Script Date: // :: ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[Category]( [Id] [int] IDENTITY(,) NOT NULL, [Name] [varchar]() NULL, CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO SET IDENTITY_INSERT [dbo].[Category] ON INSERT [dbo].[Category] ([Id], [Name]) VALUES (, N'Cat') INSERT [dbo].[Category] ([Id], [Name]) VALUES (, N'Dog') INSERT [dbo].[Category] ([Id], [Name]) VALUES (, N'Tiger') SET IDENTITY_INSERT [dbo].[Category] OFF
以上內(nèi)容就是本文的全部所示,希望大家喜歡。
相關(guān)文章
SQL Server2017使用IP作為服務(wù)器名連接服務(wù)器
本文主要介紹了SQL Server2017使用IP作為服務(wù)器名連接服務(wù)器,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
一步步教你建立SQL數(shù)據(jù)庫的表分區(qū)
分區(qū)存儲提高了數(shù)據(jù)庫的性能,被分區(qū)存儲的數(shù)據(jù)物理上是多個文件,但邏輯上任然是一個表,對表的任何操作都跟沒分區(qū)之前一樣。插入、刪除、查詢、更新等操作的時候,數(shù)據(jù)庫會自動為你找到對應(yīng)的分區(qū),然后執(zhí)行操作。2015-09-09
SQL語句中的ON DUPLICATE KEY UPDATE使用
本文主要介紹了SQL語句中的ON DUPLICATE KEY UPDATE使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
sqlserver 日志恢復(fù)方法(搞定drop和truncate)
這是一次數(shù)據(jù)恢復(fù)中,我們老大在Sql中敲的,我這里最想記錄的是他優(yōu)良的代碼風(fēng)格.2009-10-10
SQL Server2019數(shù)據(jù)庫之簡單子查詢的具有方法
這篇文章主要介紹了SQL Server2019數(shù)據(jù)庫之簡單子查詢的具有方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
SQL SERVER連線查詢數(shù)據(jù)源IP地址及開啟SQL的IP地址連線方法
這篇文章主要介紹了SQL SERVER連線查詢數(shù)據(jù)源IP地址及開啟SQL的IP地址連線方法,文中通過圖文結(jié)合的形式給大家介紹的非常詳細,具有一定的參考價值,需要的朋友可以參考下2024-06-06
uniqueidentifier轉(zhuǎn)換成varchar數(shù)據(jù)類型的sql語句
uniqueidentifier轉(zhuǎn)換成varchar數(shù)據(jù)類型的sql語句,需要的朋友可以參考下。2011-09-09

