SQL Server 关于CROSS APPLY 和 OUTER APPLY应用
<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应用的更多相关文章
- SQL Server中CROSS APPLY和OUTER APPLY的应用详解
SQL Server数据库操作中,在2005以上的版本新增加了一个APPLY表运算符的功能.新增的APPLY表运算符把右表表达式应用到左表表达式中的每一行.它不像JOIN那样先计算那个表表达式都可以, ...
- SQL Server连接查询之Cross Apply和Outer Apply的区别及用法(转载)
先简单了解下cross apply的语法以及会产生什么样的结果集吧!示例表: SELECT * FROM tableA CROSS APPLY tableB 两张表直接连接,不需要任何的关联条件,产生 ...
- <转>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 ...
- SQL Server中CROSS APPLY和OUTER APPLY应用
1.什么是Cross Apply和Outer Apply ? 我们知道SQL Server 2000中有Cross Join用于交叉联接的.实际上增加Cross Apply和Outer Apply是用 ...
- SQL SERVER使用 CROSS APPLY 与 OUTER APPLY 连接查询
概述 CROSS APPLY 与 OUTER APPLY 可以做到: 左表一条关联右表多条记录时,我需要控制右表的某一条或多条记录跟左表匹配的情况. 有两张表:Student(学生表)和 S ...
- SQL 关于apply的两种形式cross apply 和 outer apply
SQL 关于apply的两种形式cross apply 和 outer apply 例子: CREATE TABLE [dbo].[Customers]( ) COLLATE Chinese_PRC_ ...
- SQL 关于apply的两种形式cross apply 和 outer apply(转)
转载链接:http://www.cnblogs.com/shuangnet/archive/2013/04/02/2995798.html apply有两种形式: cross apply 和 oute ...
- SQL关于apply的两种形式cross apply和outer apply(转载)
SQL 关于apply的两种形式cross apply 和 outer apply apply有两种形式: cross apply 和 outer apply 先看看语法: <lef ...
- 转:SQL 关于apply的两种形式cross apply 和 outer apply
原文地址:http://www.cnblogs.com/Leo_wl/archive/2013/04/02/2997012.html SQL 关于apply的两种形式cross apply 和 out ...
随机推荐
- 对MSF八个原则的思考
第一个原则,也是MSF中最基础的一个原则,推动信息共享与沟通.这个原则的一个特点是,对于团队成员的所有工作,都会被记录下来,包括走了弯路的.出现bug但已调试解决的部分.对于新加入团队的成员或者以前没 ...
- 《Linux内核分析》第八周学习笔记
<Linux内核分析>第八周学习笔记 进程的切换和系统的一般执行过程 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163 ...
- iOS开发线程安全问题
先来看一下代码: - (void)viewDidLoad { [super viewDidLoad]; self.testStr = @"String initial complete&qu ...
- python 中的列表(list)
一.生成一个列表 直接生成 L1 = [1, 2, 3, 4, 5] 列表解析式 >>> L2 = [x for x in range(1, 10, 2)] #从1到10的迭代,步长 ...
- Oracle 和 SQLSERVER 重新获取统计信息的方法
1. Oracle 重新获取统计信息的命令 exec dbms_stats.gather_schema_stats(ownname =>) # 需要修改 ownername options 指定 ...
- eclipse里面找不到databaseexplorer
在window==>show view==>Other==>Data Management==>Database explorer配置:在右下方点击Database Sourc ...
- PSP(5.11——5.17)以及周记录
1.PSP 5.11 14:30 20:00 130 200 Cordova A Y min 5.12 9:00 14:00 100 200 Cordova A Y min 5.13 13:30 15 ...
- SVG to Image in js
SVG to Image in js SVG to Image https://image.online-convert.com/convert-to-svg https://stackoverflo ...
- 网页性能优化之异步加载js文件
一个网页的有很多地方可以进行性能优化,比较常见的一种方式就是异步加载js脚本文件.在谈异步加载之前,先来看看浏览器加载js文件的原理. 浏览器加载 JavaScript 脚本,主要通过<scri ...
- 睡前小dp-codeforce414B-dp+一点点想法
http://codeforces.com/problemset/problem/414/B 定义一个串为好的串当这个串符合 di|di+1,1<i<k-1 给定一个n为串中元素的取值范围 ...