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. 那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)

    之前没接触过证书加密的话,对证书相关的这些概念真是感觉挺棘手的,因为一下子来了一大堆新名词,看起来像是另一个领域的东西,而不是我们所熟悉的编程领域的那些东西,起码我个人感觉如此,且很长时间都没怎么搞懂 ...

  2. 微软CMS项目 Orchard 所用到的开源项目

    研发了Orchard一年左右了,时常遇到瓶颈,总觉得力不从心,其实并不是基础不够,关键还是概念性的东西太多,一会儿这个概念名词,一会那个,关于Orchard的技术文档也的确很少,每次看起来总是焦头烂额 ...

  3. windows命令——taskmgr 1

    taskmgr.exe用于任务管理器.它显示系统中正在运行的进程. 该程序使用Ctrl+Alt+Del(一般是弹出Windows安全再点击“任务管理器”)或者Ctrl+Shift+Esc 有时候需要, ...

  4. iOS 离屏渲染的研究

    GPU渲染机制: CPU 计算好显示内容提交到 GPU,GPU 渲染完成后将渲染结果放入帧缓冲区,随后视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示. G ...

  5. Dynatree使用

    最近用到了Dynatree的树形结构,记录一下它的用法. 需求: 1.jquery.js 2.jquery-ui.custom.js 3.jquery.cookie.js 下载dynatree,放到资 ...

  6. MongoDB 分片管理

    在MongoDB(版本 3.2.9)中,分片集群(sharded cluster)是一种水平扩展数据库系统性能的方法,能够将数据集分布式存储在不同的分片(shard)上,每个分片只保存数据集的一部分, ...

  7. Sql Server系列:嵌套查询

    嵌套查询是指一个查询语句嵌套在另一个查询语句内部的查询.嵌套查询也就子查询,在SELECT子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或多个表.子查询中可以使用比较运 ...

  8. 编译opengl编程指南第八版示例代码通过

    最近在编译opengl编程指南第八版的示例代码,如下 #include <iostream> #include "vgl.h" #include "LoadS ...

  9. 用jquery.pager.js实现分页

    1.html <link href="/stylesheets/Pager.css" rel="stylesheet" type="text/c ...

  10. JQuery利用sort对DOM元素进行排序

    前言 排序对于我们是再熟悉不过了,在绝大数应用程序中都会有这样一个场景:当我们从服务器端获取一个列表时,在界面上进行渲染,我们可以会依赖于某一个规则来进行排序,当然此时绝大多数会再次与服务器进行交互来 ...