【译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正】

原文链接:传送门

伴随着SQL SERVER 2005的发布,微软增加了一个新的操作符,它允许你将一个记录集与一个函数进行关联,然后对表(或者视图)的每一个指定列应用这个函数。这个新的操作符便是APPLY操作符。技术上来说,这个操作符实际上并不是一个JOIN,但是因为它用起来像是一个JOIN,它通常被成为关联操作。APPLY操作符具有两种形式,CROSS APPLY以及OUTER APPLY,在这篇文章中,我将向你解释这两种格式的差异,并以例子来演示每种格式是如何工作的。

介绍APPLY操作符

你曾经是否想要写过一个SELECT语句来对数据集中的每一行调用表值函数或计算表值表达式?如果是的话那么你将乐于了解APPLY操作符允许你进行这样的处理。APPLY操作符具有两种形式。

第一种形式是CROSS APPLY,其使用CROSS APPLY操作符一边的集合中每一行的列值并将它们作为CROSS APPLY操作符另一边的表值函数或表达式的输入项。每次对表值函数或者表达式调用返回的行会与触发表值函数调用的值所在的行进行关联,所有关联的行的集合最后再用UNION JOIN操作符关联起来。如果对于某一个特定的调用,表值函数并没有返回任何数据行,那么表或者记录行则不会被包含在最早的结果集中,因为它们不能与任何表值函数行进行关联。

APPLY操作符能够使用的第二种格式是OUTER APPLY。当表值函数或者表达式返回数据行时,这个操作符运行得如同CROSS APPLY。但是其有一个额外的特性。当表值函数被不会返回任何行的数据行所调用时,OUTER APPLY操作符同样会返回表或者记录集。

为了更好的理解这两种形式的APPLY操作符是如何工作的。让我们来查看下每个形式的操作符的一些示例。

示例的测试数据与函数

在我能够向你演示APPLY操作符的不同示例之前,我需要创建一些测试数据和一个表值函数。我的测试数据表和函数可以在列表1中被找到:

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 ,
ProductName VARCHAR(100) ,
Price MONEY
);
INSERT INTO dbo.Product
VALUES ( 'Red Santa Suit', 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 + '%'
)

列表1:创建表和表值函数

列表1的代码创建了名为Product的表,其包含了5个不同的产品。同样我创建了一个名为SearchString的表,其包含了三个字符串。最后我创建了名为dbo.FindProductLike的表值函数。表值函数dbo.FindProductLike接受一个参数:@FindString。这个表值函数使用了提供的参数,并返回ProductName包含了传递进@FindString参数的字符串的那些数据行。

使用CROSS APPY操作符

CROSS APPLY操作符会对其所涉及的记录集中的每一行执行一个表值函数。为了演示这是如何工作的,让我来运行列表2的代码:

USE tempdb;
GO
SELECT *
FROM dbo.SearchString AS S
CROSS APPLY dbo.FindProductLike(S.String);

列表2:CROSS APPLY操作符的例子

当我运行列表2的代码,随着查询结果以文本形式来显示,我得到了如报告1的输出:

ID    String           ProductName                Price
----- ---------------- -------------------------- ---------
1 Red Red Santa Suit 199.99
1 Red Red Bells 49.99
2 Lights LED Lights 6.99

报告1:通过运行代码2产生的输出

如果你查看列表2的代码你会看到我使用CROSS APPLY操作符来将表dbo.SearchString的数据行与表值函数dbo.FindProductLike的结果进行关联。CROSS APPLY操作符使用来自于dbo.SearchString表的字符串值并且调用了表值函数dbo.FindProductLike。如果表值函数返回了任何数据行, 它们将会与dbo.SearchString的行进行关联。

结果表的前两行是由于使用了字符串值“Red”,并使用它调用表值函数dbo.FindProductLike而产生的。当“Red”被传递给表值函数时,对于那些ProductName 列包含字符“Red”的那些行,ProductName和Price列便被返回。由表值函数返回的这两行随后与包含“Red”的dbo.SearchString数据行进行关联,于是便产生了报告1所示的前两行数据。

报告的第三行的结果和前两行产生的方式是一样的,除过这次函数是用“Lights”值来调用的,其仅仅匹配了一个单独的ProductName值。因此仅仅产生了一个单独的数据行。dbo.SearchString表的最后一行,其查询列值为“Star”,其在Product表不会匹配到任何ProductName的值。所以对于包含“Star”值的dbo.SearchString数据行,在报告1中不会产生任何数据行。

----To be continued.

高级T-SQL进阶系列 (二)【上篇】:使用 APPLY操作符的更多相关文章

  1. Wireshark入门与进阶系列(二)

    摘自http://blog.csdn.net/howeverpf/article/details/40743705 Wireshark入门与进阶系列(二) “君子生非异也,善假于物也”---荀子 本文 ...

  2. Bing Maps进阶系列二:使用GeocodeService进行地理位置检索

    Bing Maps进阶系列二:使用GeocodeService进行地理位置检索 在<Bing Maps进阶系列一:初识Bing Maps地图服务>里已经对GeocodeService的功能 ...

  3. Spring Boot进阶系列二

    上一篇文章,主要分析了怎么建立一个Restful web service,系列二主要创建一个H5静态页面使用ajax请求数据,功能主要有添加一本书,请求所有书并且按照Id降序排列,以及查看,删除一本书 ...

  4. SQL 工具系列二

    1.RedGate 工具 SQL Prompt 脚步智能提示工具 脚步提示工具,轻松写入,编辑和探索SQL: SQL Prompt能根据数据库的对象名称,语法和用户编写的代码片段自动进行检索,智能的为 ...

  5. 高级java必会系列二:多线程经常使用的3个关键字:synchronized、ReentrantLock、volatile

    系列一讲解了多线程,本章讲解多线程开发中经常使用到的3个关键字synchronized.ReentrantLock.volatile. 一.synchronized 互斥锁,即操作互斥,并发线程过来, ...

  6. SQL进阶系列之11让SQL飞起来

    写在前面 SQL的性能优化是数据库使用者必须面对的重要问题,本节侧重SQL写法上的优化,SQL的性能同时还受到具体数据库的功能特点影响,这些不在本节讨论范围之内 使用高效的查询 参数是子查询时,使用E ...

  7. SQL进阶系列之7用SQL进行集合运算

    写在前面 集合论是SQL语言的根基,因为这种特性,SQL也被称为面向集合语言 导入篇:集合运算的几个注意事项 注意事项1:SQL能操作具有重复行的集合(multiset.bag),可以通过可选项ALL ...

  8. SQL进阶系列之5外连接的用法

    写在前面 SQL本身是作为一种数据提取工具而出现,使用SQL生成各种定制化报表和非定制化报表并非SQL原本用途的功能,但这并不意味着SQL无法实现这些功能. 用外连接进行行列转换(1)(行 → 列): ...

  9. 进阶系列二【绝对干货】---Quartz.Net的入门

    一.Quartz.Net是什么? Quartz.Net是一个开源的作业调度框架,OpenSymphony的开源项目,是Quartz的C#移植项目.非常适合在平时的工作中,定时轮询数据库同步,定时邮件通 ...

  10. Linq To Sql进阶系列(六)用object的动态查询与保存log篇

    动态的生成sql语句,根据不同的条件构造不同的where字句,是拼接sql 字符串的好处.而Linq的推出,是为了弥补编程中的 Data != Object 的问题.我们又该如何实现用object的动 ...

随机推荐

  1. springMVC 校验时,CustomValidationMessages.properties中的错误提示信息的中文乱码 问题

    今天在学习springmvc的校验时,遇到了CustomValidationMessages.properties配置文件的信息,才错误提示时是乱码的问题:在网上找了很多方法都没解决:最后原来是在配置 ...

  2. docker互联机制实现便捷互访

    何为容器互联 & 为何需要容器互联 容器的互联是一种让多个容器中应用进行快速交互的方式,它会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不用指定具体的 ip 地址 ...

  3. 【visio】数据可视化 - 形状数据

    visio在对数据处理方面也是有一整套的设施,用户可以用visio存储.管理对象数据,利用数据驱动图形设计,让数据形象化,并在团队沟通的时候清晰地展示数据,沟通数据. 1.属性 每个图形都可以设置多个 ...

  4. js将后台传入得时间格式化

    //格式化时间函数Date.prototype.Format = function (fmt) { var o = { "M+": this.getMonth() + 1, //月 ...

  5. animation模块的使用

    1.动画的实现-初探 import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncA ...

  6. 利用ZotFile对Zotero中的文献进行整理

    1.安装ZotFile插件 *** 以后补充 *** 2.配置ZotFile 配置 3.整理操作 (1)将文件拖进Zotero软件相应的目录(自己创建) (2)查看文件位置 (未整理之前) (3)整理 ...

  7. 了解Maven的基本知识

    我的博客地址:https://www.cnblogs.com/themysteryofhackers/p/11934540.html 更新时间:2019-11-26 一.Maven的基本概念 Mave ...

  8. 6_9 天平(UVa839)<二叉树的DFS>

    前一个ubiquous通信小工具,移动只是一个由弦和电线组成的结构五彩缤纷的东西.这种移动通常被发现悬挂在小婴儿的摇篮.图说明了一个简单的移动.它只是一个电线,悬挂的一个字符串,每一个对象的对象.它可 ...

  9. kindeditor文件上传设置文件说明为上传文件名(JSP版)

    编辑器换成kindeditor时发现文件上传后,直接点确定,<a>便签中的内容显示的是文件路径,不是我想要的文件名,我试了百度上的一些设置方法都不行的,百度上大部分都是修改pugins/i ...

  10. Django框架之ORM常用字段

    一.ORM介绍 1.ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过 ...