除了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. Eclipse 创建 Maven 项目

    本人也是新手小白,在创建 Maven 项目的时候几乎踩完了所有的坑.特此总结如下: 1.咱先选中 File -> New -> Maven Project 2.然后如下图    在这里说明 ...

  2. Struts2:搭建原理

    记录下,struts2的搭建过程: 1核心jar包: struts-2.1.8\apps\struts2-blank-2.1.8.war 解压后 在struts2-blank-2.1.8\WEB-IN ...

  3. 数据结构4_java---顺序串,字符串匹配算法(BF算法,KMP算法)

    1.顺序串 实现的操作有: 构造串 判断空串 返回串的长度 返回位序号为i的字符 将串的长度扩充为newCapacity 返回从begin到end-1的子串 在第i个字符之前插入字串str 删除子串 ...

  4. CSAPP:逆向工程【缓冲区溢出攻击】

    逆向工程[缓冲区溢出攻击] 任务描述 掌握函数调用时的栈帧结构,利用输入缓冲区的溢出漏洞,将攻击代码嵌入当前程序的栈帧中,使程序执行我们所期望的过程. 主要方法 溢出的字符将覆盖栈帧上的数据,会覆盖程 ...

  5. MFC中如何分割CString类型的数据

    [才疏学浅,难免有纰漏,若有不正确的地方,欢迎指教] MFC中有一个库函数 Tokenize(); 函数原型:CStringT Tokenize( PCXSTR pszTokens , int& ...

  6. Spring Boot项目中如何定制PropertyEditors

    本文首发于个人网站:Spring Boot项目中如何定制PropertyEditors 在Spring Boot: 定制HTTP消息转换器一文中我们学习了如何配置消息转换器用于HTTP请求和响应数据, ...

  7. 使用 App Inventor 2 开发简单的安卓小游戏

    App Inventor2 是一个简单的在线开发安卓应用程序的工具,通过此工具,我们可以很轻松地开发安卓应用. 这里介绍的是笔者自己写的一个小游戏,游戏中玩家通过左右倾斜手机控制“水库”的左右移动,收 ...

  8. 面试题-javascript-面向对象编程

    笔者在某次笔试中遇到这个题:印象很深. function ClassA() { var value=4; this.getValue= function() { return value; } thi ...

  9. LeetCode刷题笔记(6)按照索引计算int[] 数组中的和([Time Limit Exceeded]问题)

    Easy303 Easy633 package easy; public class e303 { private int[] sums; public e303(int[] nums) { sums ...

  10. Redis5源码解析-Sentinel

    简单的概念就不解释.基于Redis5.0.5 从Sentinel主函数触发 在sentinel.c文件的最后面可以发现sentinelTimer函数,这个就是Sentinel的主函数,sentinel ...