T-SQL中的APPLY用法

风流不在谈锋胜,袖手无言味最长。这篇文章主要讲述T-SQL中的APPLY用法相关的知识,希望能为你提供帮助。
原文出处:http://www.sqlservercentral.com/articles/Stairway+Series/121318/
 
从SQL Server 2005开始,微软添加了一个新的运算符用于关联一个带有函数的结果集,并把函数应用于表/视图中的每一个限定行中。这个运算符就是APPLY。从技术上来说,这个操作的底层逻辑并不是实际的“JOIN”,但由于它的用法更像是JOIN,所以通常会与关联操作相关联。APPLY操作分为两种格式:CROSS APPLY或OUTER APPLY。在本文中会分别展示这两种格式。
 
【T-SQL中的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\' ); GOCREATE 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);

 
结果如下:
 
T-SQL中的APPLY用法

文章图片

 
 
回看代码可以看到,代码中使用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);

T-SQL中的APPLY用法

文章图片

 

 
从结果中可以看出,对于字符串“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

 
T-SQL中的APPLY用法

文章图片

 

 
从结果上来看,和CROSS APPLY无异,仅仅是把表值函数换成了表值表达式。
 
 
总结:
APPLY运算可以把数据集中的数据与表值函数或表值表达式关联,使用APPLY可以针对表值函数或表达式的数据集进行基于集合的查询。在这种情况下可以考虑使用APPLY运算符。



    推荐阅读