下面把sqlserver中cross apply和outer apply關(guān)鍵字具體介紹展示如下:
1.CROSS APPLY 和OUTER APPLY
MSDN解釋如下(個(gè)人理解不是很清晰):
使用 APPLY 運(yùn)算符可以為實(shí)現(xiàn)查詢操作的外部表表達(dá)式返回的每個(gè)行調(diào)用表值函數(shù)。表值函數(shù)作為右輸入,外部表表達(dá)式作為左輸入。
通過(guò)對(duì)右輸入求值來(lái)獲得左輸入每一行的計(jì)算結(jié)果,生成的行被組合起來(lái)作為最終輸出。
APPLY 運(yùn)算符生成的列的列表是左輸入中的列集,后跟右輸入返回的列的列表。
APPLY 有兩種形式:
CROSS APPLY 和 OUTER APPLY。
CROSS APPLY 僅返回外部表中通過(guò)表值函數(shù)生成結(jié)果集的行。
OUTER APPLY 既返回生成結(jié)果集的行,也返回不生成結(jié)果集的行,其中表值函數(shù)生成的列中的值為 NULL。
網(wǎng)上搜集的解釋如下(個(gè)人感覺(jué)好理解):
SQL Server數(shù)據(jù)庫(kù)操作中,在2005以上的版本新增加了一個(gè)APPLY表運(yùn)算符的功能。新增的APPLY表運(yùn)算符把右表表達(dá)式應(yīng)用到左表表達(dá)式中的每一行。
它不像JOIN那樣先計(jì)算哪個(gè)表表達(dá)式都可以,APPLY必須先邏輯地計(jì)算左表達(dá)式。這種計(jì)算輸入的邏輯順序允許把右表達(dá)式關(guān)聯(lián)到左表表達(dá)式。
APPLY有兩種形式,一個(gè)是OUTER APPLY,一個(gè)是CROSS APPLY,區(qū)別在于指定OUTER,意味著結(jié)果集中將包含使右表表達(dá)式為空的左表表達(dá)式中的行,而指定CROSS,則相反,結(jié)果集中不包含使右表表達(dá)式為空的左表表達(dá)式中的行。
注意:若要使用 APPLY,數(shù)據(jù)庫(kù)兼容級(jí)別必須為 90。
下面我們做個(gè)例子:
比如有個(gè)類別表(Category)內(nèi)容如下:
還有個(gè)類別明細(xì)表(CategoryDetail)內(nèi)容如下:
下面我們來(lá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)出來(lái)了,當(dāng)然當(dāng)右表的信息為空(NULL)時(shí),OUTER APPLY也會(huì)在結(jié)果集中顯示出來(lái).
接下來(lái)我們看下CROSS APPLY的查詢結(jié)果:
SELECT *
FROM dbo.Category a
CROSS APPLY ( SELECT *
FROM dbo.CategoryDetail b
WHERE b.CategoryId = a.Id
) AS c ;
根據(jù)這圖和上面的比較可看出,這個(gè)返回結(jié)果只有兩個(gè),Category 表中的Tiger的信息沒(méi)有帶出來(lái),因?yàn)樵贑ategoryDetail 表中沒(méi)有對(duì)應(yīng)的明細(xì).
由以上信息可得出,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)鍵字會(huì)從左表 (Category) 那里返回所有的行,即使在右表 (CategoryDetail) 中沒(méi)有匹配的行。
注釋:在某些數(shù)據(jù)庫(kù)中, LEFT JOIN 稱為 LEFT OUTER JOIN。
下面我們來(lái)看看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)鍵字會(huì)從左表 (Category) 那里返回所有的行,即使在右表 (CategoryDetail) 中沒(méi)有匹配的行。效果和OUTER APPLY 一樣。
OUTER APPLY 和 LEFT JOIN 的主要區(qū)別為:
一個(gè)LEFT JOIN 關(guān)鍵字只能JOIN 一個(gè)表,不能解決一個(gè)復(fù)雜的SELECT 語(yǔ)句,或者函數(shù)方法等。
一個(gè)OUTER APPLY 關(guān)鍵字可以包含一個(gè)獨(dú)立的復(fù)雜的SELECT 語(yǔ)句,或者其他函數(shù)方法等。
OUTER APPLY 和 LEFT JOIN 性能的區(qū)別:
通過(guò)本文總結(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)容就是本文的全部所示,希望大家喜歡。
您可能感興趣的文章:- SQL語(yǔ)句的各個(gè)關(guān)鍵字的解析過(guò)程詳細(xì)總結(jié)
- sql連接查詢中,where關(guān)鍵字的位置講解
- sql中的left join及on、where條件關(guān)鍵字的區(qū)別詳解
- Mysql帶And關(guān)鍵字的多條件查詢語(yǔ)句
- MySQL單表多關(guān)鍵字模糊查詢的實(shí)現(xiàn)方法
- MySQL 5.7中的關(guān)鍵字與保留字詳解
- SQL中一些小巧但常用的關(guān)鍵字小結(jié)