zoukankan      html  css  js  c++  java
  • sql server cross/outer apply 用法

    这是 sql server 帮助文档关于apply的描述:

          使用 APPLY 运算符(2005或以上版本)可以为实现查询操作的外部表表达式返回的每个行调用表值函数。表值函数作为右输入,外部表表达式作为左输入。通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出。APPLY 运算符生成的列的列表是左输入中的列集,后跟右输入返回的列的列表。

          APPLY 有两种形式: CROSS APPLY 和 OUTER APPLY。CROSS APPLY 仅返回外部表中通过表值函数生成结果集的行。OUTER APPLY 既返回生成结果集的行,也返回不生成结果集的行,其中表值函数生成的列中的值为 NULL。

    看一下例子:

    select * from table1 join MyFunction(1) on 1=1

    MyFunction 的参数是一个常量,可以返回一个表。

    但有时候我们希望以 table1 的字段作为参数,传进函数去计算,像:

    select * from table1 join MyFunction(id) on 1=1

    这样是会出错的。这个时候我们就可以用 apply 来实现了。例如:

    select * from table1 cross apply MyFunction(id) on 1=1

    简单的说,apply 允许我们将前面结果集每一行的数据作为参数,传递到后面的表达式,后面的表达式可以是一个表值函数,或者select结果集。

    实际项目应用:

    产品表和点击率统计表,按产品最近一个月点击率排序。

    如果不用apply,实现起来就比较麻烦,用 apply 实现起来大概就是这样的:

    ;with cteResult as(
       select row_number() over(order by HitCount) as rowid, 
              ProductID,
              ProductName 
         from ProductInfo pi with(nolock) 
        outer apply(select sum(HitCount) HitCount from HitStatisticsInfo hsi 
        where hsi.TargetID = pi.ProductID
          and hsi.HitTime >= '2015-08-08' 
        group by TargetID) hsi 
        where pi.IsDel = 0) 
    select * from cteResult where rowid between 1 and 20
    

    至于 cross apply 与 outer apply 的区别就好像left join 与 join 的区别。如果 apply 不生成行,outer apply 也会返回该行,而 cross apply 则不会输出该行。

    so,当你在需要将某个字段的值作为参数使用时,或者用join实现起来比较复杂时,就可以考虑apply来实现。

  • 相关阅读:
    SpringMVC案例3----spring3.0项目拦截器、ajax、文件上传应用
    TCP/IP、UDP、 Http、Socket的差别
    HttpClient 图讲解明
    数据库设计--数据的垂直拆分
    未经处理的异常在 System.Data.dll 中发生。其它信息:在应使用条件的上下文(在 '***' 附近)中指定了非布尔类型的表达式。
    VMware 下扩展linux硬盘空间
    cocos2d_android 第一个游戏
    解决安卓程序安装没图标的问题
    Qt编译错误GL/gl.h: No such file or directory
    【编程题目】二元树的深度
  • 原文地址:https://www.cnblogs.com/4littleProgrammer/p/4747355.html
Copyright © 2011-2022 走看看