除了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. VSCode 配置 Python 开发环境

    一.环境准备 首先需要先安装好 Python 和 VSCode, 下载地址如下 VSCode Python 二.安装 Python 扩展 首先在VSCode上安装 Python 扩展,如图: 三.新建 ...

  2. 01 Python简介、环境搭建及包管理(一)

    一.Python简介 1. Python的特点: 是一门动态.解释型.强类型语言 动态:在运行期间才做数据检查(不用提前声明变量)- 静态语音(C/Java):编译时检查数据类型(编码时需要声明变量类 ...

  3. 第3次作业-MOOC学习笔记:Python网络爬虫与信息提取

    1.注册中国大学MOOC 2.选择北京理工大学嵩天老师的<Python网络爬虫与信息提取>MOOC课程 3.学习完成第0周至第4周的课程内容,并完成各周作业 4.提供图片或网站显示的学习进 ...

  4. OptimalSolution(2)--二叉树问题(3)Path路径问题

    一.在二叉树中找到累加和为指定值的最长路径长度 给定一棵二叉树和一个32位整数sum,求累加和为sum的最长路径长度.路径是指从某个节点往下,每次最多选择一个孩子节点或者不选所形成的节点链 -3 / ...

  5. 实战--dango自带的分页(极简)

    注意,我将templates定义在项目的同级目录下: 在settings.py中配置 TEMPLATES = [ { 'BACKEND': 'django.template.backends.djan ...

  6. apply 、 call 、 bind的用法

    1.apply 方法 apply:调用一个对象的一个方法,用另一个对象替换当前对象.例如:B.apply(A, arguments);即A对象应用B对象的方法. apply方法最多只能有两个参数——新 ...

  7. redis入门(三)

    目录 redis入门(三) 目录 前言 事务 原理 Lua脚本 安装 脚本命令 集群搭建工具 redis-trib.rb redis官方集群搭建 集群横向扩展 故障转移 redis管理 参考文档 re ...

  8. SpringBoot自定义starter及自动配置

    SpringBoot的核心就是自动配置,而支持自动配置的是一个个starter项目.除了官方已有的starter,用户自己也可以根据规则自定义自己的starter项目. 自定义starter条件 自动 ...

  9. 我的【Java】面试日记

    背景 在老东家五年了,总共工作整七年,经历两家公司.2019-10-31日离职.公司规模较小,项目压力不大,非985/211毕业,统招本科,计算机专业.目标:中大型公司,最好是大厂,嘿嘿,不过不抱希望 ...

  10. 使用position设置经典的网站前端结构

    能脱离文档流的设置: float:left/right position:absolute; 绝对定位 position:fixed; 固定定位 //搞清楚position的属性值的意思就容易明白 使 ...