除了CROSS JOIN, INNER JOIN, OUTER JOIN之外,T-SQL还提供了CROSS APPLY和OUTER APPLY这两个较为另类的Set操作符。

首先来看CROSS APPLY。跟CROSS JOIN一样,MSDN只在FROM Clause的文档中做了一个介绍,如下:

Both the left and right operands of the APPLY operator are table expressions. The main difference between these operands is that the right_table_source can use a table-valued function that takes a column from the left_table_source as one of the arguments of the function. The left_table_source can include table-valued functions, but it cannot contain arguments that are columns from the right_table_source.

The APPLY operator works in the following way to produce the table source for the FROM clause:
Evaluates right_table_source against each row of the left_table_source to produce rowsets.
The values in the right_table_source depend on left_table_source. right_table_source can be represented approximately this way: TVF(left_table_source.row), where TVF is a table-valued function.
Combines the result sets that are produced for each row in the evaluation of right_table_source with the left_table_source by performing a UNION ALL operation.

The list of columns produced by the result of the APPLY operator is the set of columns from the left_table_source that is combined with the list of columns from the right_table_source.

简单来说就是,APPLY操作符的过程就是:

  1. 计算左表表达式
  2. 将左表表达式结果作为右表输入

通常,对右表表达式,即可以是表,也可以为Function。

例一,右表表达式为Function,左表中名为Tags的Column保存了多个Key拼接而成的字符串。如Tags为“abc, def, acd”

-- Define functions
if object_id('parsetags','TF') is not null
drop function parsetags;
GO
create function parsetags(
@tags nvarchar(1000),
@splits varchar(10)
)
returns @t_tags TABLE (tag nvarchar(100))
as
begin
set @tags = RTrim(LTrim(@tags))
set @i = CharIndex(@splits,@tags) while @i >= 1
begin
insert @t_tags Values(Left(@tags,@i-1))
set @tags = SubString(@tags,@i+1,Len(@tags)-@i)
set @i = CharIndex(@Splits,@tags)
end if @tags <> ''
insert @t_tags Values (@tags)
return;
end
GO -- Define table t_blog
CREATE TABLE t_blog
(
blogid INT NOT NULL,
blogcontent NVARCHAR(MAX) NOT NULL,
tags NVARCHAR(200) NOT NULL
)
GO -- Example of CROSS APPLY
SELECT * FROM t_blog CROSS APPLY parsetags(t_blog.tags, ';')
GO

例二,右表表达式为另外一张表,选出每个Customer最大的两笔Sales订单。

-- Create Customer table
CREATE TABLE t_customer
(
[id] NVARCHAR(50) NOT NULL,
[name] NVARCHAR(50) NOT NULL
)
GO -- Create Sales table
CREATE TABLE t_sales
(
[id] NVARCHAR(50) NOT NULL,
[custid] NVARCHAR(50) NOT NULL,
[amount] MONEY NOT NULL
)
GO -- Using cross apply
SELECT t_customer.[id] as custid, t_customer.[name] as custname, sales.[id] as saleid, sales.[amount] as salesamount
FROM t_customer
CROSS APPLY
(SELECT top 2 *
FROM t_sales
WHERE t_customer.id = t_sales.custid
ORDER BY amount) AS sales
GO

以上都是使用CROSS APPLY做例子,而OUTER APPLY与其的主要区别是,OUTER APPLY会左表表达式中存在而右表表达式运算结果为NULL的项目,跟INNER JOIN跟OUTER JOIN的概念完全一致。

用例二作为说明:

  • 使用CROSS APPLY时,没有任何Sales的Customer在结果集中不显示;
  • 用OUTER APPLY时,没有Sales的Customer也会在结果集中出现,但其对应的saleid和saleamount都为NULL

是为之记。
Alva Chien
2016.6.14

T-SQL Part VIII: CROSS APPLY, OUTER APPLY的更多相关文章

  1. SQLSERVER表联结(INNER JOIN,LEFT JOIN,RIGHT JOIN,FULL JOIN,CROSS JOIN,CROSS APPLY,OUTER APPLY)

    1 常用表联结(inner join,left join,right join,full join,cross join) if object_id(N'table1',N'U') is not nu ...

  2. 初识cross apply & outer apply

    1. 2. 3.参考地址: http://blog.csdn.net/htl258/article/details/4537421

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

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

  4. CROSS APPLY vs OUTER APPLY

    Apply 工作原理:    Apply操作符让符合查询的每一条记录都调用一次TVF函数,并将结果与原数据表的记录内容一起展开.    Apply操作符定义在From子句内,使用方式与Join操作符类 ...

  5. CROSS APPLY和 OUTER APPLY 区别详解

    SQL Server 2005 新增 cross apply 和 outer apply 联接语句,增加这两个东东有啥作用呢? 我们知道有个 SQL Server 2000 中有个 cross joi ...

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

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

  7. sql server cross/outer apply 用法

    这是 sql server 帮助文档关于apply的描述: 使用 APPLY 运算符(2005或以上版本)可以为实现查询操作的外部表表达式返回的每个行调用表值函数.表值函数作为右输入,外部表表达式作为 ...

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

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

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

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

随机推荐

  1. Django实现WebSSH操作Kubernetes Pod

    优秀的系统都是根据反馈逐渐完善出来的 上篇文章介绍了我们为了应对安全和多分支频繁测试的问题而开发了一套Alodi系统,Alodi可以通过一个按钮快速构建一套测试环境,生成一个临时访问地址,详细信息可以 ...

  2. App自动化环境搭建

    1.安装Appium-desktop工具 下载地址:https://github.com/appium/appium-desktop/releases/tag/v1.8.2 2.安装Android环境 ...

  3. java架构之路-(Redis专题)Redis的主从、哨兵和集群

    我们使用的redis,单机的绝对做不到高可用的,万一单机的redis宕机了,就没有备用的了,我们可以采用集群的方式来保证我们的高可用操作. 主从架构 大致就是这样的,一个主节点,两个从节点(一般两个就 ...

  4. PHP list的赋值

    List右边的赋值对象是一个以数值为索引的数组,左边的变量的位置和赋值对象的键值一一对应,有些位置的变量可以省略不写.非末尾的被赋值变量省略时,分隔的逗号不能省略.左边变量被赋值的顺序是从右到左的. ...

  5. 自学maya三月,为啥还是95%都还不会,那是因为你不懂这几个技巧

    有一些学员经常会有这种疑问,为什么学习MAYA软件这么难,为什么自己怎么学都学不会? 结果调查,发现了下面几个问题. 游戏建模 第一: 走弯路 很多人一开始学习Maya的时候肯定第一步是安装软件,但是 ...

  6. caffe中softmax源码阅读

    (1) softmax函数                                      (1) 其中,zj 是softmax层的bottom输入, f(zj)是softmax层的top输 ...

  7. Redis实战篇

    Redis实战篇 1 Redis 客户端 1.1 客户端通信 原理 客户端和服务器通过 TCP 连接来进行数据交互, 服务器默认的端口号为 6379 . 客户端和服务器发送的命令或数据一律以 \r\n ...

  8. 深入理解Transformer及其源码解读

    深度学习广泛应用于各个领域.基于transformer的预训练模型(gpt/bertd等)基本已统治NLP深度学习领域,可见transformer的重要性.本文结合<Attention is a ...

  9. SpringBoot之配置文件的注入

    @PropertySource&@ImportResource&@Bean @PropertySource:加载指定的配置文件: /** * 将配置文件中配置的每一个属性的值,映射到这 ...

  10. ICollection IEnumerable/IEnumerator IDictionaryEnumerator yield

    Enumerable和IEnumerator接口是.NET中非常重要的接口,二者区别: 1. IEnumerable是个声明式的接口,声明实现该接口的类就是“可迭代的enumerable”,但并没用说 ...