SQL Server 2005(含)以上版本,新增了APPLY表运算,为我们日常查询带来了极大的方便。

  新增的APPLY表运算符把右表表达式应用到左表表达式中的每一行。它不像JOIN那样先计算那个表表达式都可以,APPLY必选先逻辑地计算左表达式。这种计算输入的逻辑顺序允许吧右表达式关联到左表表达式。

  APPLY有两种形式,一个是OUTER APPLY,一个是CROSS APPLY,区别在于指定OUTER,意味着结果集中将包含使右表表达式为空的左表表达式中的行,而指定CROSS,则相反,结果集中不包含使右表表达式为空的左表表达式中的行。

  用几个例子解释这个会更清晰。

  例1:CROSS APPLY 形式

  比如:LargeTable表中的某一列存储的数据是以“:”号分隔的数据,我们处理的时候,可能要先把这个值,先分隔,然后把分隔后的每个值单独一行放在一张表中,然后对这个表做处理。

  原始数据(LargeTable表):
  

  为了简单,我们先拿其中id=2的一行处理,这些以:号分隔的数据,可能是我们某张表的主键(t1),我们可能需要把这些数值提出来,放在一张临时表中,和t1表关联,做一些处理。

  处理这个分隔的数据结果如下图:

  

  如果用之前的版本处理这个操作的话,应该很发杂,暂时没想到怎么处理,如果有人实现过,可以提示一下。

  这只是用其中一行做的处理,如果我们用上图的3行都做这样处理,把三行以:号分隔的数值都放在一个表中,该怎么处理呢?

  今天的主角APPLY该闪亮登场了。用APPLY表运算符一行语句就能处理以上操作。

  

SELECT a FROM dbo.LargeTable AS LT    --实际表
CROSS APPLY dbo.split(LT.Name,':')    --自定义表值函数,处理以某个字符分隔的数据,把这些数据,返回一张表
WHERE a <> '' --去掉结果表中a字段为空的数据

  处理的结果如下图:

  

  是不是很简单。

需要额外定义的就是那个自定义表值函数(split),这是我在网上找的,类似.Net中Split操作,代码如下:

  


/*
    使用方法:SELECT * FROM dbo.split('581::579::519::279::406::361::560',':')
*/
ALTER Function [dbo].[Split](@Sql varchar(8000),@Splits varchar(10))
returns @temp Table (a varchar(100))
As
Begin
    Declare @i Int
    Set @Sql = RTrim(LTrim(@Sql))
    Set @i = CharIndex(@Splits,@Sql)
    While @i >= 1
    Begin
    Insert @temp Values(Left(@Sql,@i-1))
    Set @Sql = SubString(@Sql,@i+1,Len(@Sql)-@i)
    Set @i = CharIndex(@Splits,@Sql)
End If @Sql <> ''
Insert @temp Values (@Sql)
Return
End

  例2:OUTER APPLY 形式

  场景:有个供货商表(Supplier)和供货商产品表(Products),我们要取每一个供货商中单价最高的两个产品。

  供货商表:

  

  供货商产品表:

  

  首先,我们创建一个自定义表值函数(dbo.fn_top_products),该函数根据供货商ID返回单价最高的两个商品。


IF OBJECT_ID('dbo.fn_top_products') IS NOT NULL
    DROP FUNCTION dbo.fn_top_products;
GO
--根据供货商ID获得单价最高的两件商品
CREATE FUNCTION dbo.fn_top_products
    (@supid AS INT)
    RETURNS TABLE
AS
RETURN
    SELECT TOP(2)Id AS ProductId,ProductName,UnitPrice
    FROM dbo.Products
    WHERE SupplierId = @supid
    ORDER BY UnitPrice DESC
GO

好,前期的数据都已经准备好了,下面让我们试试用OUTER APPLY形式来查询,会出现什么结果。

执行以下语句:

SELECT S.id AS SupplierId,S.CompanyName,UnitPrice FROM dbo.Supplier AS S
OUTER APPLY dbo.fn_top_products(S.id) AS P

  执行结果如下:

   

  注意最后为NULL的记录,reed公司因为没有商品,所以单价为NULL了。

  如果用CROSS APPLY形式,执行以下查询:

  

SELECT S.id AS SupplierId,S.CompanyName,UnitPrice FROM dbo.Supplier AS S
CROSS APPLY dbo.fn_top_products(S.id) AS P   

  生成的输出结果如下:

    

  大家看出OUTER APPLY和CROSS APPLY的区别了吧。

  再次说一下APPLY的执行过程,它先逻辑计算左表表达式(以上的LargeTable表),然后把右表达式(以上的自定义表值函数Split)应用到左表表达式的每一行。实际是把外部查询的列引用作为参数传递给表值函数。

SQL Server:APPLY表运算符的更多相关文章

  1. SQL Server里PIVOT运算符的”红颜祸水“

    在今天的文章里我想讨论下SQL Server里一个特别的T-SQL语言结构——自SQL Server 2005引入的PIVOT运算符.我经常引用这个与语言结构是SQL Server里最危险的一个——很 ...

  2. SQL server 2005 PIVOT运算符的使用

    原文:SQL server 2005 PIVOT运算符的使用 PIVOT,UNPIVOT运算符是SQL server 2005支持的新功能之一,主要用来实现行到列的转换.本文主要介绍PIVOT运算符的 ...

  3. 千万级SQL Server数据库表分区的实现

    千万级SQL Server数据库表分区的实现 2010-09-10 13:37 佚名 数据库 字号:T | T 一般在千万级的数据压力下,分区是一种比较好的提升性能方法.本文将介绍SQL Server ...

  4. Azure 意外重启, 丢失sql server master表和 filezilla

    突然发现今晚网站打不开了,提示连不上数据库. ftp也连不上了. 远程连上Azure 发现机器意外重启, 丢失sql server master表和 filezilla 要重新安装. 又耗费我几个小时 ...

  5. SQL Server 系统表简介

    SQL Server 系统表简介 系统目录是由描述SQL Server 系统的数据库.基表.视图和索引等对象的结构的系统表组成.SQL Server 经常访问系统目录,检索系统正常运行所需的必要信息. ...

  6. [SQL]SQL Server数据表的基础知识与增查删改

    SQL Server数据表的基础知识与增查删改 由张晨辉(学生) 于19天 前发表 | 阅读94次 一.常用数据类型 .整型:bigint.int.smallint.tinyint .小数:decim ...

  7. SQL Server 锁表、查询被锁表、解锁相关语句

    SQL Server 锁表.查询被锁表.解锁相关语句,供参考. --锁表(其它事务不能读.更新.删除) BEGIN TRAN SELECT * FROM <表名> WITH(TABLOCK ...

  8. SQL SERVER 数据库表同步复制 笔记

    SQL SERVER 数据库表同步复制 笔记 同步复制可运行在不同版本的SQL Server服务之间 环境模拟需要两台数据库192.168.1.1(发布),192.168.1.10(订阅) 1.在发布 ...

  9. Sql Server 判断表或数据库是否存在

    发布:thebaby   来源:脚本学堂     [大 中 小] 本文详细介绍了,在sql server中判断数据库或表是否存在的方法,有理论有实例,有需要的朋友可以参考下,一定有帮助的.原文地址:h ...

随机推荐

  1. JavaScript面向对象之我见

    序言 在JavaScript的大世界里讨论面向对象,都要提到两点:1.JavaScript是一门基于原型的面向对象语言 2.模拟类语言的面向对象方式.对于为什么要模拟类语言的面向对象,我个人认为:某些 ...

  2. 高灵活度,高适用性,高性能,轻量级的 ORM 实现

    ORM(Object-Relational Mapping 对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,目的是提供易于理解的模型化数据的方法. ORM虽然有诸多好处,但是在实 ...

  3. C#开发EyeLink眼动仪的实验程序

    [题外话] Eyelink眼动仪是SR Research推出的一款眼动仪,很多高校都在使用其做实验.其官方提供了COM的接口,所以支持COM接口的开发平台都可以开发使用.官方甚至提供了一个C#的样例供 ...

  4. MySQL 子分区

    200 ? "200px" : this.width)!important;} --> 介绍 子分区其实是对每个分区表的每个分区进行再次分隔,目前只有RANGE和LIST分区 ...

  5. DDN - Digital Data Network

    DDN(Digital Data Network,数字数据网)是一种利用光纤.数字微波或卫星等数字传输通道和数字交叉复用设备组成的数字数据传输网.它可以为用户提供各种速率的高质量数字专用电 数字数据网 ...

  6. fir.im Weekly - 让 iOS 应用更加安全

    攻易防难,关于 iOS 应用安全看起来有些神秘.iOS Security , 源于@吴发伟_则平博客翻译的关于iOS安全的一系列文章,现在站点已经系统收集了大量关于 iOS 逆向.安全.反编译.静动态 ...

  7. Android Studio使用技巧:导出jar包

    转自http://blog.csdn.net/lincyang/article/details/44457799 AS中并没有独立的Module 工程,但是可以在普通的Project中加入Module ...

  8. Easyui 让DataGrid适应浏览器宽度

    DataGrid有100%宽度的设置,但是有时不是很让人满意,比如你你放大或者拉放你的浏览器,那么DataGrid只维持第一次加载的宽高,非常难看 $('#List').datagrid({ url: ...

  9. Android音视频之MediaPlayer音视频播放

    前言: 昨天总结了视频录制,今天来学习一下视频的播放,Android的视频播放主要采用MediaPlayer类. MediaPlayer介绍 MediaPlayer类可用于控制音频/视频文件或流的播放 ...

  10. WordPress上传含有中文文件出现乱码

    最近打算学习安装配置WordPress,当然同时也在学习PHP+MySQL,希望以后能做一些关于WordPress定制和二次开发,包括主题和插件.在成功安装WordPress3.5中文版之后,就测试了 ...