SQL Server 一些关键字详解(一)

摘要:
CROSSAPPLY仅返回外部表中通过表值函数生成结果集的行。在线收集的解释如下:在SQL Server数据库操作中,2005以上版本中添加了APPLY表运算符。新的APPLY表操作符将右表表达式应用于左表表达式中的每一行。让我们看一下LEFTJOIN:1SELECT*2FROMdbo的查询结果。类别3LEFTJOINdbo。类别详细信息bONb。类别Id=Id;ViewCodeLEFTJOIN关键字将返回左表中的所有行,即使右表中没有匹配的行。OUTERAPPLY和LEFTJOIN之间的主要区别在于,LEFTJON关键字只能JOIN一个表,不能解决复杂的SELECT语句或函数方法。因此,建议可以使用LEFTJOIN的用户不要使用OUTRAPPLY。
1.CROSS APPLY OUTER APPLY

MSDN解释如下(个人理解不是很清晰):

使用 APPLY 运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数。表值函数作为右输入,外部表表达式作为左输入。通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出。APPLY 运算符生成的列的列表是左输入中的列集,后跟右输入返回的列的列表。

APPLY 有两种形式:CROSS APPLY 和 OUTER APPLYCROSS APPLY 仅返回外部表中通过表值函数生成结果集的行。OUTER APPLY 既返回生成结果集的行,也返回不生成结果集的行,其中表值函数生成的列中的值为 NULL

 

网上搜集的解释如下(个人感觉好理解):

SQL Server数据库操作中,在2005以上的版本新增加了一个APPLY表运算符的功能。新增的APPLY表运算符把右表表达式应用到左表表达式中的每一行。它不像JOIN那样先计算哪个表表达式都可以,APPLY必须先逻辑地计算左表达式。这种计算输入的逻辑顺序允许把右表达式关联到左表表达式。

APPLY有两种形式,一个是OUTER APPLY,一个是CROSS APPLY,区别在于指定OUTER,意味着结果集中将包含使右表表达式为空的左表表达式中的行,而指定CROSS,则相反,结果集中不包含使右表表达式为空的左表表达式中的行

 

注意:若要使用 APPLY,数据库兼容级别必须为 90

 

下面我们做个例子:

比如有个类别表(Category)内容如下:

SQL Server 一些关键字详解(一)第1张

 

还有个类别明细表(CategoryDetail)内容如下:

SQL Server 一些关键字详解(一)第2张

 

 

下面我们来看看OUTER APPLY 的查询结果:

1 SELECT  *
2 FROM    dbo.Category a
3         OUTER APPLY ( SELECT    *
4                       FROM      dbo.CategoryDetail b
5                       WHERE     b.CategoryId = a.Id
6                     ) AS c ;

SQL Server 一些关键字详解(一)第3张

由上图可看出OUTER APPLY把左表中的信息查出后把右表中的信息也关联出来了,当然当右表的信息为空(NULL)时,OUTER APPLY也会在结果集中显示出来.

 

接下来我们看下CROSS APPLY的查询结果:

1 SELECT  *
2 FROM    dbo.Category a
3         CROSS APPLY ( SELECT    *
4                       FROM      dbo.CategoryDetail b
5                       WHERE     b.CategoryId = a.Id
6                     ) AS c ;

SQL Server 一些关键字详解(一)第4张

根据这图和上面的比较可看出,这个返回结果只有两个,Category 表中的Tiger的信息没有带出来,因为在CategoryDetail 表中没有对应的明细.

由以上信息可得出,OUTER APPLY 就相当于数学中的并集,CROSS APPLY相当于数学中的交集,关于交集与并集的介绍如下:

并集为下图中的所有红色部分,即为AB的全部:

SQL Server 一些关键字详解(一)第5张

交集为下图中的红色部分,也就是AB相交的部分:

SQL Server 一些关键字详解(一)第6张

2.OUTER APPLY LEFT JOIN

LEFT JOIN 关键字会从左表 (Category) 那里返回所有的行,即使在右表 (CategoryDetail) 中没有匹配的行。

注释:在某些数据库中, LEFT JOIN 称为 LEFT OUTER JOIN

 

下面我们来看看LEFT JOIN 的查询结果(还是1.CROSS APPLY 和 OUTER APPLY中的例子):

SQL Server 一些关键字详解(一)第7张SQL Server 一些关键字详解(一)第8张
1 SELECT  *
2 FROM    dbo.Category a
3         LEFT JOIN dbo.CategoryDetail b ON b.CategoryId = a.Id ;
View Code

SQL Server 一些关键字详解(一)第9张

LEFT JOIN 关键字会从左表 (Category) 那里返回所有的行,即使在右表 (CategoryDetail) 中没有匹配的行。效果和OUTER APPLY 一样。

OUTER APPLY 和 LEFT JOIN 的主要区别为:

  一个LEFT JOIN 关键字只能JOIN 一个表,不能解决一个复杂的SELECT 语句,或者函数方法等。

  一个OUTER APPLY 关键字可以包含一个独立的复杂的SELECT 语句,或者其他函数方法等。

 

OUTER APPLY 和 LEFT JOIN 性能的区别:

  据这博客LEFT JOIN和OUTER APPLY性能比较的总结可知 LEFT JOIN 要比 OUTER APPLY 性能要快。所以建议能用LEFT JOIN的尽量不要用OUTER APPLY

 

附注:

附Category 表和CategoryDetail 表的结果及插入数据的脚本:

SQL Server 一些关键字详解(一)第10张SQL Server 一些关键字详解(一)第11张
 1 CREATE TABLE [dbo].[CategoryDetail](
 2     [Id] [int] IDENTITY(1,1) NOT NULL,
 3     [CategoryId] [int] NULL,
 4     [Cry] [varchar](50) NULL,
 5  CONSTRAINT [PK_CategoryDetail] PRIMARY KEY CLUSTERED 
 6 (
 7     [Id] ASC
 8 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
 9 ) ON [PRIMARY]
10 GO
11 SET ANSI_PADDING OFF
12 GO
13 SET IDENTITY_INSERT [dbo].[CategoryDetail] ON
14 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (1, 1, N'')
15 INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (2, 2, N'')
16 SET IDENTITY_INSERT [dbo].[CategoryDetail] OFF
17 /****** Object:  Table [dbo].[Category]    Script Date: 08/17/2015 18:24:03 ******/
18 SET ANSI_NULLS ON
19 GO
20 SET QUOTED_IDENTIFIER ON
21 GO
22 SET ANSI_PADDING ON
23 GO
24 CREATE TABLE [dbo].[Category](
25     [Id] [int] IDENTITY(1,1) NOT NULL,
26     [Name] [varchar](50) NULL,
27  CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED 
28 (
29     [Id] ASC
30 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
31 ) ON [PRIMARY]
32 GO
33 SET ANSI_PADDING OFF
34 GO
35 SET IDENTITY_INSERT [dbo].[Category] ON
36 INSERT [dbo].[Category] ([Id], [Name]) VALUES (1, N'Cat')
37 INSERT [dbo].[Category] ([Id], [Name]) VALUES (2, N'Dog')
38 INSERT [dbo].[Category] ([Id], [Name]) VALUES (3, N'Tiger')
39 SET IDENTITY_INSERT [dbo].[Category] OFF
View Code

免责声明:文章转载自《SQL Server 一些关键字详解(一)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇全球最大的3D数据集公开了!标记好的10800张全景图nginx 启动错误下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

js引用类型赋值不改变原对象值

在JS中,对象的赋值是指默认情况下的赋值。如果更改指定对象,原始对象也将更改。如果要复制赋值,需要重新分配对象:vara={'name':'zhangsan'};varb=对象。分配b、 name='lisi';这样,原始对象的下一层的值不会更改,但如果对象中存在对象,下一层也会更改下一层中的原始对象。处理两个对象的相关性有一个简单而激烈的问题:obj1={...

Python3 读取和写入excel

/py_工作/销售/包括/天气。csv'_工作簿函数读取并返回所有工作表● 以列表形式读取_仅:判断是否读取_仅以模式打开Excel文档● 编码:...

python爬取图片遇见src乱码: data:image/png;base64

Python抓取图像并遇到src乱码:data:image/png;Base64会抓取您喜欢的图像,但图像的src在抓取的代码中出现了乱码:data:image/png;base64.)“”头1,编码=字符串。splitdata=b64decodedwithopenasf:f.写入。close()注意:我还没有成功。。。。。。...

【原生】CocosCreator Android和游戏的通讯 (Java和TS互相调用、传递JSON数据、监听返回键)

Cocos版本:2.4.4参考:Cocos文档-Java原生反射机制Cocos文档-JSB使用指南-在Cocos中调用Android方法2在Android中调用Cocos方法3传输JSON数据4倾听返回键5 Cocos和Android相互调用时遇到的问题,TypeScript方法可以在Java中调用,Java方法可以在TypeScript中调用。在Cocos...

db2数据导出导入del与ixf格式

ixf格式保存的是结构和数据,是一个二进制文件,ixf文件不可视。...

CSS躬行记(8)——裁剪和遮罩

裁剪最早是在CSS2.1时代由clip属性引入,但该属性只能应用于绝对定位的元素,并且只能裁剪成矩形。CSS3提供了强大的clip-path属性,突破了clip属性的众多限制,接下来将围绕clip-path属性展开讲解。3)裁剪路径对于复杂的形状,可以采用SVG来创建裁剪路径,实现自定义。2)替换元素的填充和定位CSS3引入了两个新属性,用于遮罩替换元素。...