先看看语法:

<left_table_expression>  {cross|outer} apply<right_table_expression>

再让我们了解一下apply运算涉及的两个步骤:

A1:把右表表达式(<right_table_expression>)应用到左表(<left_table_expression>)输入的行

A2:添加外部行;

  使用apply就像是先计算左输入,然后为左输入中的每一行计算一次右输入。(这一句很重要,可能会不理解,但要先记住,后面会有详细的说明)

最后结合以上两个步骤说明cross apply和outer apply的区别

  crossapply和outer apply 总是包含步骤A1,只有outer apply包含步骤A2,如果crossapply左行应用右表表达式时返回空积,则不返回该行。而outer apply返回行,并且该行的右表表达式的属性为null。

看到上面的解释或步骤大家可能还是一头的雾水,不知所云。

下面用例子来说明:

--表一([dbo].[Customers]  字段说明:customerid--消费者id, city -- 所在城市):
CREATE TABLE [dbo].[Customers](
[customerid][char](5)NOTNULL,
[city][varchar](10)NOTNULL,
PRIMARY KEY CLUSTERED ( [customerid]ASC)WITH(IGNORE_DUP_KEY=OFF)ON [PRIMARY]
) ON [PRIMARY]
--向表一插入数据:
insert into dbo.Customersvalues('FISSA','Madrid');
insert into dbo.Customersvalues('FRNDO','Madrid');
insert into dbo.Customersvalues('KRLOS','Madrid');
insert into dbo.Customersvalues('MRPHS','Zion');
--表二([dbo].[Orders] 字段说明:orderid--订单id ,customerid -- 消费者id):
CREATE TABLE [dbo].[Orders](
[orderid] [int]NOT NULL,
[customerid][char](5)NULL,
PRIMARY KEY CLUSTERED ([orderid]ASC)WITH(IGNORE_DUP_KEY=OFF)ON [PRIMARY]
) ON [PRIMARY]
--向表二插入数据:
insert into dbo.Ordersvalues(1,'FRNDO');
insert into dbo.Ordersvalues(2,'FRNDO');
insert into dbo.Ordersvalues(3,'KRLOS');
insert into dbo.Ordersvalues(4,'KRLOS');
insert into dbo.Ordersvalues(5,'KRLOS');
insert into dbo.Ordersvalues(6,'MRPHS');
insert into dbo.Ordersvalues(7,null);
--查询插入的数据:
select *from dbo.Customers
select *from dbo.orders
结果:
customerid city
---------- ----------
FISSA Madrid
FRNDO Madrid
KRLOS Madrid
MRPHS Zion (4 行受影响) orderid customerid
----------- ----------
1 FRNDO
2 FRNDO
3 KRLOS
4 KRLOS
5 KRLOS
6 MRPHS
7 NULL (7 行受影响)

【例子】得到每个消费者最新的两个订单:

1、用cross apply

SELECT  *
FROM dbo.CustomersAS A
CROSS APPLY( SELECT TOP 2 *
FROM dbo.OrdersAS B
WHERE A.customerid= B.customerid
ORDER BY orderid DESC
) AS AB;

结果:

customerid city       orderid     customerid
---------- ---------- ---------------------
FRNDO Madrid 2 FRNDO
FRNDO Madrid 1 FRNDO
KRLOS Madrid 5 KRLOS
KRLOS Madrid 4 KRLOS
MRPHS Zion 6 MRPHS

过程分析:

  它是先得出左表【dbo.Customers】里的数据,然后把此数据一条一条的放入右表表式中,分别得出结果集,最后把结果集整合到一起就是最终的返回结果集了(T1的数据 像for循环一样 一条一条的进入到T2中 然后返回一个集合 最后把所有的集合整合到一块 就是最终的结果),最后我们再理解一下上面让记着的话(使用apply就像是先计算左输入,让后为左输入中的每一行计算一次右输入)。

2、用outer apply

SELECT  *
FROM dbo.CustomersAS A
OUTER APPLY( SELECT TOP 2
*
FROM dbo.OrdersAS B
WHERE A.customerid= B.customerid
ORDER BY orderid DESC
) AS AB;

结果:

customerid city       orderid     customerid
---------- ---------- ---------------------
FISSA Madrid NULL NULL
FRNDO Madrid 2 FRNDO
FRNDO Madrid 1 FRNDO
KRLOS Madrid 5 KRLOS
KRLOS Madrid 4 KRLOS
MRPHS Zion 6 MRPHS

结果分析:

  发现outerapply得到的结果比cross多了一行,我们结合上面所写的区别(cross apply和outer apply 总是包含步骤A1,只有outer apply包含步骤A2,如果cross apply左行应用右表表达式时返回空积,则不返回该行。而outerapply返回改行,并且改行的右表表达式的属性为null)就会知道了。

【例二】

;with tb1(客户号,销售日期,销售额)AS(
select '001','2017-05-01',460 union all
select '001','2017-05-02',240 union all
select '001','2017-05-03',300
),TB2(客户号,付款额)AS(
select '001',500
)
SELECT t1.客户号 ,
t1.销售日期 ,
t1.销售额 ,
CASE WHEN t2.付款额 <= ISNULL(tt1.p_销售额, 0) THEN 0
ELSE CASE WHEN ( ISNULL(p_销售额, 0) + t1.销售额 ) >= t2.付款额
THEN t2.付款额 - ISNULL(p_销售额, 0)
ELSE t1.销售额
END
END AS 实付额
FROM tb1 AS t1
CROSS APPLY ( SELECT SUM(付款额) AS 付款额
FROM TB2
WHERE TB2.客户号 = t1.客户号
) AS t2
OUTER APPLY ( SELECT SUM(销售额) AS p_销售额
FROM tb1 AS tt
WHERE tt.客户号 = t1.客户号
AND tt.销售日期 < t1.销售日期
) AS tt1; --结果
客户号 销售日期 销售额 实付额
---- ---------- ----------- -----------
001 2017-05-01 460 460
001 2017-05-02 240 40
001 2017-05-03 300 0

SQL Server 关于CROSS APPLY 和 OUTER APPLY应用的更多相关文章

  1. SQL Server中CROSS APPLY和OUTER APPLY的应用详解

    SQL Server数据库操作中,在2005以上的版本新增加了一个APPLY表运算符的功能.新增的APPLY表运算符把右表表达式应用到左表表达式中的每一行.它不像JOIN那样先计算那个表表达式都可以, ...

  2. SQL Server连接查询之Cross Apply和Outer Apply的区别及用法(转载)

    先简单了解下cross apply的语法以及会产生什么样的结果集吧!示例表: SELECT * FROM tableA CROSS APPLY tableB 两张表直接连接,不需要任何的关联条件,产生 ...

  3. <转>SQL Server CROSS APPLY and OUTER APPLY

    Problem SQL Server 2005 introduced the APPLY operator, which is like a join clause and it allows joi ...

  4. SQL Server中CROSS APPLY和OUTER APPLY应用

    1.什么是Cross Apply和Outer Apply ? 我们知道SQL Server 2000中有Cross Join用于交叉联接的.实际上增加Cross Apply和Outer Apply是用 ...

  5. SQL SERVER使用 CROSS APPLY 与 OUTER APPLY 连接查询

    概述 CROSS APPLY 与 OUTER APPLY 可以做到:      左表一条关联右表多条记录时,我需要控制右表的某一条或多条记录跟左表匹配的情况. 有两张表:Student(学生表)和 S ...

  6. SQL 关于apply的两种形式cross apply 和 outer apply

    SQL 关于apply的两种形式cross apply 和 outer apply 例子: CREATE TABLE [dbo].[Customers]( ) COLLATE Chinese_PRC_ ...

  7. SQL 关于apply的两种形式cross apply 和 outer apply(转)

    转载链接:http://www.cnblogs.com/shuangnet/archive/2013/04/02/2995798.html apply有两种形式: cross apply 和 oute ...

  8. SQL关于apply的两种形式cross apply和outer apply(转载)

    SQL 关于apply的两种形式cross apply 和 outer apply   apply有两种形式: cross apply 和 outer apply   先看看语法:   <lef ...

  9. 转:SQL 关于apply的两种形式cross apply 和 outer apply

    原文地址:http://www.cnblogs.com/Leo_wl/archive/2013/04/02/2997012.html SQL 关于apply的两种形式cross apply 和 out ...

随机推荐

  1. 龟速机器学习总结----day1

    机器学习主要工作大致分为以下几步,数据预处理,包括数据切分,特征选取,数据缺失值处理,来了解数据.接下来分割数据,分别分出训练集和测试集.第三步,选择模型,使用训练数据训练模型参数,再对测试数据进行预 ...

  2. linux内核设计第七周——可执行程序的装载

  3. SE Springer小组之《Spring音乐播放器》需求分析说明书二

    2.1 目标 Spring音乐播放器软件为课程<软件工程>所开发的课程作业,主要意图是为访问计算机中的mp3格式的音频文件,并使其能够完成访问,读取,添加,保存,播放,切换音频文件等功能. ...

  4. servlet请求转发

    来源:http://www.2cto.com/kf/201610/554591.html 请求转发:Servlet(源组件)先对客户请求做一些预处理操作(数据处理),然后把请求转发给其他Web组件(目 ...

  5. 8 commands to check cpu information on Linux

    https://www.binarytides.com/linux-cpu-information/

  6. Java的Spring内实现的mini版内存"计数器"功能

    工期紧急,不让用Redis,自己实现了一个Spring内的mini版内存"计数器"功能,很简陋,和业务耦合太紧密,需要改进. public Long getCreationCoun ...

  7. eclipse集成tomcat日志文件输出配置

    eclipse集成tomcat日志文件输入配置 2015-07-21 00:13 1072人阅读 评论(0) 收藏 举报  分类: tomcat(1)  eclipse Where can I vie ...

  8. python 安装influxdb-python

    一.Linux下安装 1.yum install -y git 2.安装pip,参考:https://app.yinxiang.com/shard/s41/sh/0338ba85-5443-453f- ...

  9. js regex variable & Set, Map

    js regex variable & Set, Map regex, variable, Set, Map, 交集, 差集, 并集, https://stackoverflow.com/qu ...

  10. php技术–php中感叹号!和双感叹号!!的用法(三元运算)

    ---恢复内容开始--- if(文章==有用){狂点我;} 在php持术或其他语言中我们经常会看到感叹号的用法,有一定程序语言基础的朋友都知道单个感叹号的作用是取反的意思,也就是取当前结果的反面,如: ...