T-SQL中的APPLY用法
原文出处:http://www.sqlservercentral.com/articles/Stairway+Series/121318/
从SQL Server 2005开始,微软添加了一个新的运算符用于关联一个带有函数的结果集,并把函数应用于表/视图中的每一个限定行中。这个运算符就是APPLY。从技术上来说,这个操作的底层逻辑并不是实际的“JOIN”,但由于它的用法更像是JOIN,所以通常会与关联操作相关联。APPLY操作分为两种格式:CROSS APPLY或OUTER APPLY。在本文中会分别展示这两种格式。
APPLY 简介:
你是否曾经写过SELECT语句去调用一个表值函数或把表值表达式的每一个记录与表匹配?如果有过这样的经历,APPLY运算符会帮到你。APPLY分为CROSS APPLY和OUTER APPLY。
第一种格式叫CROSS APPLY。它从CROSSAPPLY的一边提取表或数据集的每行的所需列值,然后作为输入值传输到另外一边的表值函数或表达式中。然后把所有关联的值使用UNION ALL运算符合并。如果表值函数针对输入数据没有满足调用条件时,函数将不返回输出,并且这部分的表或结果集将不会出现在最终结果中,因为它不能与表值函数的数据关联。
第二种格式叫OUTER APPLY。其行为和CROSSAPPLY类似,但返回不能调用表值函数/表达式的值。
为了更好理解这两种格式,下面来演示一下:
测试数据和函数:
USE tempdb;
GO
IF object_id('dbo.Product') IS NOT NULL
DROP TABLE dbo.Product;
IF object_id('dbo.SearchString') IS NOT NULL
DROP TABLE dbo.SearchString;
IF object_id('dbo.FindProductLike') IS NOT NULL
DROP FUNCTION dbo.FindProductLike; CREATE TABLE dbo.Product
(
ID INT IDENTITY ,
ProductNameVARCHAR(100) ,
Price MONEY
);
INSERT INTO dbo.Product
VALUES ( 'Red SantaSuit', 199.99 ),
( 'Candy Canes', 1.99 ),
( 'Fake Snow', 2.99 ),
( 'Red Bells', 49.99 ),
( 'LED Lights', 6.99 ); CREATE TABLE dbo.SearchString
(
ID INT IDENTITY ,
String VARCHAR(100)
); INSERT INTO dbo.SearchString
VALUES ( 'Red' ),
( 'Lights' ),
( 'Star' );
GO CREATE FUNCTION dbo.FindProductLike
(
@FindString VARCHAR(100)
)
RETURNS TABLE
AS
RETURN
( SELECT ProductName,
Price
FROM dbo.Product
WHERE ProductName LIKE '%' + @FindString + '%'
)
创建表和表值函数
上面的脚本中创建了一个叫做Product的表,包含了5个不同的产品。同时也创建了一个叫做SearchString的表,包含了3个不同的字符串。最后创建一个叫做FindProductLike的表值函数。该函数接收一个@FindString参数,并在Product表中找出所有包含@FindString的ProductName。
使用CROSS APPLY 运算符:
CROSS APPLY会对相关联的每一行都应用该函数
USE tempdb;
GO
SELECT *
FROM dbo.SearchString AS S
CROSS APPLYdbo.FindProductLike(S.String);
结果如下:

回看代码可以看到,代码中使用CROSSAPPLY关联SearchString表中的结果集和FindProductLike表值函数。CROSS APPLY从SearchString中获取String值,然后调用函数FindProductLike。如果函数返回数据,则与SearchString的行关联。
前两行的数据来自于字符串“Red”,当“Red”传输给函数后,返回包含该值的ProductName和Price,然后和SearchString关联,把包含“Red”值的产品返回到结果集中。第三行数据和前两行的产生原理一致,但是是由“Lights”产生。字符串“Star”由于没有在Product中得到匹配值,所以不返回结果。
使用OUTER APPLY 运算符:
该操作符和CROSS APPLY的唯一区别是返回所有数据,包括没有匹配的值:
USE tempdb;
GO
SELECT *
FROM dbo.SearchString AS S
OUTER APPLYdbo.FindProductLike(S.String);

从结果中可以看出,对于字符串“Star”,OUTER APPLY也返回结果,只是返回NULL。
使用表值表达式:
下面演示一下使用表值表达式与APPLY的操作。
USE tempdb;
GO
SELECT * FROM dbo.SearchString as S
CROSS APPLY
(SELECT ProductName, Price
FROM dbo.Product
WHERE ProductName like '%' + S.String + '%') as X

从结果上来看,和CROSS APPLY无异,仅仅是把表值函数换成了表值表达式。
总结:
APPLY运算可以把数据集中的数据与表值函数或表值表达式关联,使用APPLY可以针对表值函数或表达式的数据集进行基于集合的查询。在这种情况下可以考虑使用APPLY运算符。
T-SQL中的APPLY用法的更多相关文章
- SQL中distinct的用法
SQL中distinct的用法 1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...
- sql中binary_checksum(*)的用法
sql中binary_checksum(*)的用法(转) binary_checksum(*)可以用来检查修改过的行. 同一行在update后,该行的binary_checksum(*)就不同. 如 ...
- SQL中Merge的用法
SQL中Merge的用法 Merge的用法 Merge可以完成以下功能: 1. 两个表之间数据的更新 2. 进行进销存更新库存 3. 进行表之间数据的复制 语法说明: 1. 在语句结束后一定要 ...
- SQL中Truncate的用法(转)
转自:http://www.studyofnet.com/news/555.html 本文导读:删除表中的数据的方法有delete,truncate, 其中TRUNCATE TABLE用于删除表中的所 ...
- sql中 decode() 的用法
sql中 decode() 的用法 SELECT ID,DECODE(inParam,'Param','value1' ,'value2') name FROM yytj2018 如果 inParam ...
- 十、SQL中EXISTS的用法 十三、sql server not exists
十.SQL中EXISTS的用法 EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False EXISTS 指定一个子查询,检测 行 的存在. 语法 ...
- SQL中Truncate的用法
SQL中Truncate的用法转自:http://www.studyofnet.com/news/555.html本文导读:删除表中的数据的方法有delete,truncate, 其中TRUNCATE ...
- SQL中CONVERT()函数用法详解
SQL中CONVERT函数格式: CONVERT(data_type,expression[,style]) 参数说明: expression 是任何有效的 Microsoft® SQL Server ...
- SQL中CASE 的用法 转载
sql语言中有没有类似C语言中的switch case的语句?? 没有,用case when 来代替就行了. 例如,下面的语句显示中文年月 select getdat ...
- SQL中的declare用法
平时写SQL查询.存储过程都是凭着感觉来,没有探究过SQL的具体语法,一直都是按c#那一套往SQL上模仿,前几天项目中碰到一个问题引起了我对declare定义变量的作用域的兴趣. 大家都知道c#中的局 ...
随机推荐
- C# ModBus Tcp读写数据 与服务器进行通讯
前言 本文将使用一个NuGet公开的组件技术来实现一个ModBus TCP的客户端,方便的对Modbus tcp的服务器进行读写,这个服务器可以是电脑端C#设计的,也可以是PLC实现的,也可以是其他任 ...
- C# 时间控件 竖直进度条 饼图显示 仪表盘 按钮基础控件库
Prepare 本文将使用一个NuGet公开的组件来实现一些特殊的控件显示,方便大家进行快速的开发系统. 在Visual Studio 中的NuGet管理器中可以下载安装,也可以直接在NuGet控制台 ...
- css文本是否换行
关于文本换行有三个属性: white-space word-break word-wrap white-space normal 默认.空白会被浏览器忽略 pre 空白会被浏览器保留.其行为方式类似 ...
- 在MySQL中快速的插入大量测试数据
很多时候为了测试数据库设计是否恰当,优化SQL语句,需要在表中插入大量的数据,怎么插入大量的数据就是个问题了. 最开始想到的办法就是写一个程序通过一个很大的循环来不停的插入,比如这样: int i = ...
- robot framework下载文件操作
不同的浏览器点击[下载]按钮之后,需要点击保存,还是确定,或者直接默认直接下载都是不一样的 1.chrome:点击[下载]之后,会自动执行下载操作,直到下载结束 A)点击下载,等待下载结束(sleep ...
- python基础-闭包
def bibao(): li = [] n = [1] def inner(): li.append(n[0]) n[0] +=1 print(li) return inner b = bibao( ...
- PythonStudy——编程基础 Python Primary
1.什么是编程语言 语言: 一个事物与另外一个事物沟通的介质 .编程语言是程序员与计算机沟通的介质. 编程: 将人类内识别的语言转化为机器能识别的指令,这种过程就叫做编程. 注:最终这些指令会被转化 ...
- Django学习笔记之数据库-QuerySet_API
QuerySet API 我们通常做查询操作的时候,都是通过模型名字.objects的方式进行操作.其实模型名字.objects是一个django.db.models.manager.Manager对 ...
- Property referenced in indexed property path is neither an array nor a List nor a Map
记一次传参请求报错,没有解决 Invalid property 'distributeCars[0][ackStatus]' of bean class [com.api6.plate.prototy ...
- 如何从 VSS 迁移到Team Foundation Server
TFS 2012自带了vss upgrade wizard工具, 在Team Foundation Server管理控制台左侧的最后一个菜单其他工具和组件中,选择Visual SourceSafe升级 ...