1.CROSS APPLY 和OUTER APPLY

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

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

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

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

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

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

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

下面我们做个例子:

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

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

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

 SELECT  *
FROM dbo.Category a
OUTER APPLY ( SELECT *
FROM dbo.CategoryDetail b
WHERE b.CategoryId = a.Id
) AS c ;

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

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

 SELECT  *
FROM dbo.Category a
CROSS APPLY ( SELECT *
FROM dbo.CategoryDetail b
WHERE b.CategoryId = a.Id
) AS c ;

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

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

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

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

2.OUTER APPLY 和LEFT JOIN

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

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

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

 SELECT  *
FROM dbo.Category a
LEFT JOIN dbo.CategoryDetail b ON b.CategoryId = a.Id ;

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 表的结果及插入数据的脚本:

 CREATE TABLE [dbo].[CategoryDetail](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CategoryId] [int] NULL,
[Cry] [varchar](50) 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 (1, 1, N'喵')
INSERT [dbo].[CategoryDetail] ([Id], [CategoryId], [Cry]) VALUES (2, 2, N'汪')
SET IDENTITY_INSERT [dbo].[CategoryDetail] OFF
/****** Object: Table [dbo].[Category] Script Date: 08/17/2015 18:24:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Category](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) 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 (1, N'Cat')
INSERT [dbo].[Category] ([Id], [Name]) VALUES (2, N'Dog')
INSERT [dbo].[Category] ([Id], [Name]) VALUES (3, N'Tiger')
SET IDENTITY_INSERT [dbo].[Category] OFF

SQL Server 一些关键字详解(一)的更多相关文章

  1. SQL Server 一些关键字详解(二)

    1.LEFT JOIN 容易让人误解的地方 背景:因为在网上搜了下 LEFT JOIN 和 OUTER APPLY 的区别,时发现,有的网友解释为: 1) A   left  join  B  的连接 ...

  2. MS SQL Server 数据库连接字符串详解

    MS SQL Server 数据库连接字符串详解 原地址:http://blog.csdn.net/jhhja/article/details/6096565 问题 : 超时时间已到.在从池中获取连接 ...

  3. SQL Server表分区详解

    原文:SQL Server表分区详解 什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆 ...

  4. sql server 存储过程的详解

    SqlServer存储过程详解 1.创建存储过程的基本语法模板: if (exists (select * from sys.objects where name = 'pro_name')) dro ...

  5. JDBC连接SQL Server 2005步骤详解

    一.设置SQL Server服务器:    1.“开始” → “程序” → “Microsoft SQL Server 2005” → “配置工具” → “SQL Server Configurati ...

  6. SQL Server 性能优化详解

    故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册用户较少,网站性能表现不错,但随着注册用户的增多,访问速度开始变慢,一些用户开始发来邮件表示抗议,事情变得越来越糟,为了留住用户, ...

  7. [转]MS SQL Server 数据库连接字符串详解

    http://blog.csdn.net/jackiehome/article/details/8668121 问题 : 超时时间已到.在从池中获取连接之前超时时间已过.出现这种情况可能是因为所有池连 ...

  8. SQL server T-SQL索引详解

    SQL索引在数据库优化中占有一个非常大的比例,一个好的索引的设计,可以让sql语句查询效率提高很多被. 1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引的主要目的是提高T-SQL系统 ...

  9. Sql Server之数据类型详解

      数据类型是一种属性,用于指定对象可保存的数据的类型,SQL Server中支持多种数据类型,包括字符类型.数值类型以及日期类型等.数据类型相当于一个容器,容器的大小决定了装的东西的多少,将数据分为 ...

随机推荐

  1. 【Unity Shaders】学习笔记——SurfaceShader(一)认识结构

    [Unity Shaders]学习笔记——SurfaceShader(一)认识结构 转载请注明出处:http://www.cnblogs.com/-867259206/p/5595747.html 写 ...

  2. OC项目中使用Swift

    1.在OC工程中新建 Swift 文件,会提示的是否创建一个桥接文件,创建不创建都无所谓,这个桥接文件主要是用来包含OC头文件的,主要用于Swift中使用OC         2.在Person.sw ...

  3. C语言中的fread和fwrite

    C语言中的fread和fwrite是专门用来操作文件的方法. 1. fread负责从打开的文件指针中读取文件内容. 函数原型:size_t fread(void *p, size_t size, si ...

  4. PfSense基于BSD的软件防火墙的安装、配置与应用

    PfSense基于BSD的软件防火墙的安装.配置与应用 PfSense是一个FreeBSD下的免费开源的防火墙和路由器软件,他为了在X86平台上面建立一个高集成性的防火墙项目,下面就为大家展示如何配置 ...

  5. cordova local notification plugin

    cordova plugin add org.apache.cordova.device cordova plugin add https://github.com/katzer/cordova-pl ...

  6. 【python】基础

    [字符串]前后引号必须要匹配,相关函数int(),float(),str(),repr(),format(),还有切片运算符 a = 'text'           单引号指定的字符串必须在一个逻辑 ...

  7. ios开发之OC基础-类和对象

    本系列的文章主要来自于个人在学习前锋教育-欧阳坚老师的iOS开发教程之OC语言教学视频所做的笔记,边看视频,边记录课程知识点.建议大家先过一遍视频,在看视频的过程中记录知识点关键字,把把握重点,然后再 ...

  8. 获取本地IP地址信息

    2012-06-05    /// <summary>         /// 获取本地IP地址信息         /// </summary>         void G ...

  9. 检查字符串长度 检查字符串是否为空 用正则表达式验证出版物的ISBN号 用正则表达式验证邮证编码 验证字符串中是否含有汉字

    <?php /** * 常用的正则表达式来验证信息.如:网址 邮箱 手机号等 */ class check { /** * 正则表达式验证email格式 * * @param string $s ...

  10. Android IOS WebRTC 音视频开发总结(十三)-- ice原理

    以前在做一个视频监控项目的时候,刚开始客户没提到要支持P2P,因为服务端是我们自己写的,为了便于处理一些逻辑,全部采用转发的方式,后来客户要求支持P2P,没办法了,后来自己部署了一个STUN服务器(不 ...