SQL Server中以apply运算符简化join和子查询_sql server apply join_矛盾星媛的博客-程序员宅基地

技术标签: sql server  


关系数据库中涉及多表操作会使查询变复杂。 多个表的查询,常用的操作方法就是使用表联接(join)或子查询。在sql server 2005中新增了apply运算符, 它能简化原来用join或子查询解决问题的方式。

   

示例, 系统有两个表, 一个文章表和一个文章评论表, 一对多的关系。
创建表结构代码
       

SQL code

if object_id(N'article_comment') is not null
drop table article_comment;

if object_id(N'article') is not null
drop table article;

create table article(
 id int primary key,
 title nvarchar(200) not null,
 content nvarchar(max) not null
);

create table article_comment(
 id int identity primary key,
 content nvarchar(1000) not null,
 article_id int not null,
 add_date datetime not null
);
             
插入测试数据
     

SQL code

insert into article ( id, title, content )
select 1, 'title1', 'content1' union
select 2, 'title2', 'content2' union
select 3, 'title3', 'content3' union
select 4, 'title4', 'content4' union
select 5, 'title5', 'content5' union
select 6, 'title6', 'content6' union
select 7, 'title7', 'content7'

insert into article_comment ( content, article_id, add_date )
select 'comment1', 1, '2014-11-11' union all
select 'comment2', 1, '2014-11-12' union all
select 'comment3', 1, '2014-11-13' union all
select 'comment1', 2, '2014-11-14' union all
select 'comment1', 3, '2014-11-15' union all
select 'comment2', 3, '2014-11-16' union all
select 'comment3', 3, '2014-11-17' union all
select 'comment1', 4, '2014-11-18' union all
select 'comment2', 4, '2014-11-19' union all
select 'comment1', 5, '2014-11-20' union all
select 'comment2', 5, '2014-11-21' union all
select 'comment3', 5, '2014-11-22' union all
select 'comment5', 5, '2014-11-23' union all
select 'comment6', 5, '2014-11-24' union all
select 'comment7', 5, '2014-11-25' ;
      
现在要通过查询得到文章表的全部字段加上文章的评论数和最新的评论日期。
               
第一种方案通过子查询来实现
     

SQL code

select id, title, content,
  (select COUNT(*) from article_comment where a.id = article_id ) as comment_count,
  (select MAX( add_date ) from article_comment where a.id = article_id ) as max_comment_date
 from article as a ;
 
  
这个查询中有两个字查询, 分别要查两次article_comment(文章评论) 表, 这是低效的做法
   
第二种方案通过联接(join)实现
     

SQL code

select id, title, content,
  b.comment_count,
  b.max_comment_date
 from article as a
  left join ( select COUNT(*) as comment_count,
        MAX( add_date ) as max_comment_date,
        article_id
        from article_comment
        group by article_id
   ) as b on a.id = b.article_id
  
这种方案比上一种方案要好, 但显的过于复杂, 在联接查询中还嵌套了一层group by 聚合。

第三种方案能过apply运算符实现
   

SQL code

select id, title, content, t.comment_count, t.max_comment_date
 from article as a outer apply (
  select COUNT(*) as comment_count,
      MAX( add_date ) as max_comment_date
   from article_comment as ac
   where a.id = ac.article_id
 ) as t;
    
    这种方案的执行计划与第二种相似, 但从查询复杂性来讲, 要比第二种更清晰, 至少少了一个group by 子句。 apply和join的区别在于, join所运算的左右两部份是先执行迪卡尔乘积(交叉联接)生成结果后再进行条件筛选, 而apply可以在执行迪卡尔乘积之前事先进行条件筛选并且还可以对结果集进行处理, 这样在某些需要运算而得到结果再进行合并的情况下会比较方便。在这个查询中使用了outer apply, 其实把outer apply换成 cross apply也同样可行, 因为在这个查询中无法体现outer apply和cross apply的区别。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013180028/article/details/49425325

智能推荐

欧拉函数的C实现_欧拉函数c语音_PolluxAvenger的博客-程序员宅基地

/************************************************************************ FileName      : 文件名* Version       : 版本* Description  : 对此文件的描述* Author        : 文件作者* Created       : 建立日期* Histo

服务器不稳定对网站造成哪些影响,企业如何选择合适的服务器?_软件工程师郭刚的博客-程序员宅基地

  服务器是打开网站必要载体,服务器对网站的运行提供动力,以及让网站在网络中实行数据交换。如果服务器不稳定,直接导致网站的正常运营和推广。我们在打开网页的时候,会遇到代码500报错,即是服务器遇到错误。网站建设公司凌聚科技来先看看服务器不稳定的表现有哪些? 阿里云服务器:https://www.aliyun.com/minisite/goods?userCode=pbr3yqtc 服务器不稳定的表现有: 1、网站加载时快时慢; 2、网站...

中国剩余定理学习小结_Old_Veteran的博客-程序员宅基地

中国剩余定理学习小结:我们知道crt是用来合并n个一元线性同余方程,时间复杂度是O(n)。具体如下:x≡a1 (mod m1)x≡a2 (mod m2)x≡a3 (mod m3)....x≡an (mod mn)怎样合并呢?假设整数M=m1*m2....*mn;(保证m1..mn互质。)设Mi=M/mi;(i=1..n;)即除了mi外n-1个数的乘积。设ti为Mi的数论倒数,即

org.apache.catalina.loader.WebappClassLoaderBase clearReferencesJdbc问题_org.apache.catalina.loader.webappclassloaderbase.c_何处是天涯的博客-程序员宅基地

The web application [] registered the JDBC driver [com.alibaba.druid.proxy.DruidDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has ...

简述Session与Cookie区别_zwt2001267的博客-程序员宅基地

Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用C...

evc大赛高分案例_第六届中国国际“互联网+”大学生创新创业大赛浙江省高教主赛道优秀项目第一期训练营成功举办..._weixin_39624864的博客-程序员宅基地

9月14日至15日,第六届中国国际“互联网+”大学生创新创业大赛浙江省高教主赛道优秀项目第一期训练营在浙江工商大学成功举办。本期训练营由浙江省大学生创新创业大赛组委会组办,浙江工商大学承办,旨在贯彻落实《教育部关于举办第六届中国国际“互联网+”大学生创新创业大赛的通知》及我省相关文件精神,进一步激发高校学生创新创业热情,提高各校参赛作品质量。 9月14日上午举行了...

随便推点

CISCO-配置终端访问服务器_hqmln的博客-程序员宅基地

终端访问服务器实际上就是有8个或16个异步口的路由器,从它引出的多条连接线到各个路由器上的Console口,使用时,首先登陆到终端访问服务器,然后从终端访问服务器再登陆到各个路由器。终端访问服务器的使用可以避免在配置多台路由器时频繁插拔Console线。作终端访问服务器需要相关硬件环境:cisco的2509和2511或者终端访问服务模块;   2509路由器提供了一个异步接口,可接一根八...

DOS程序员手册(七)_weixin_30575309的博客-程序员宅基地

第11章 中断处理程序 本章将深入到DOS系统内部探讨中断处理程序的内容。与其他计算机编程不一样,中断处理程序这个名词听起来就很难懂。用最简单的话来说,中断处理程序就是对应于中断激活的程序。 读者可能已发现,中断处理实际上并不是件很难办的事。事实上,在某些地方中断处理很容易管理。但是,其中仍然有些“黑洞”,一旦陷入便不能自拔。本章的信息可让你不致于...

【鼠】安卓学习杂记(二十四)——Android之Adapter之SimpleAdapter(简单适配器(不常用)——需写简单的布局文件)_訾博ZiBo的博客-程序员宅基地

一、效果图二、XML代码自定义布局文件:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_wid...

oracle order by 为空,Oracleorderby处理NULL值_金融四十人论坛的博客-程序员宅基地

1、缺省处理 Oracle在Order by 时缺省认为null是最大值,所以如果是ASC升序则排在最后,DESC降序则排在最前2、使用nvl函数 nvl函1、缺省处理Oracle在Order by 时缺省认为null是最大值,所以如果是ASC升序则排在最后,DESC降序则排在最前2、使用nvl函数nvl函数可以将输入参数为空时转换为一特定值,如nvl(employee_name,’张三’)表示当...

推荐文章

热门文章

相关标签