SQL Server中With As的介绍与应用(三)--递归的实战应用

前言

前一篇《SQL Server中With As的介绍与应用(二)--递归的使用》我们介绍了一下SQL中With As的递归应用,本章我们直接通过递归的方式实战操作一下,看看使用的效果。

报表要求

我们要查2019-05-20到2019-05-31的销售数据,列出每天的销售额是多少,大概的要求如下图

销售表的数据源

按日期分组看一下

从结果上看只有2019-05-22的销售数据,如果要实现上面的报表样子相用这个select查询是少了很多天的数据。

今天我们就用普通实现和用With As实现两种实现方式来看看怎么实现这个报表查询。


普通实现方式

普通实现试的思路:

  1. 先创建个临时表

  2. 把选择的日期数据先插入进去

  3. 然后跟据数据源的数据更新临时表数据

  4. 查询临时表数据生成报表

代码实现

--定义变量开始日期和结束日期还有临时销售表
declare @sdate datetime,@edate datetime
declare @tbxs table(销售日期 datetime,销售额 decimal(19,4))
--赋值开始和结束日期
select @sdate='2019-05-20'
select @edate='2019-05-31'


--把所有日期数据先插入销售额为0
while(@sdate<=@edate)
begin
  insert into @tbxs(销售日期,销售额)
  values(@sdate,0)
  select @sdate=dateadd(day, 1, @sdate)
end


--更新临时表中数据的信息
update V set 销售额=b.销售额 from @tbxs V,
(select 销售日期,SUM(销售金额) as 销售额 from 商品流水表
group by 销售日期) b where V.销售日期=b.销售日期


--显示最后的报表信息
select * from @tbxs

实现效果

上面可以看出来我们用普通的实现方式,需要定义一个临时表,并且对临时表先插入后修改的操作,最后再查询用于实现。

接下来再看看With As的实现


With As实现

With As实现思路:

  1. 利用With As实现开始日期到结束日期的递归

    利用With As实现把销售数据分组

  2. 通过上面两个组合的数据用左连接直接查询

我们上一篇中说过,With As可以设置多个,中间用(,)逗号分隔即可,所以我们上面的两个算到一步去了。

代码实现

--定义变量开始日期和结束日期还有临时销售表
declare @sdate datetime,@edate datetime
--赋值开始和结束日期
select @sdate='2019-05-20'
select @edate='2019-05-31'


--用With As把开始日期和结束日期进行递归生成公共名为“日期”的表
--把销售数据分组查询出来生成公共名为"销售"的表
;with 日期 as(
   select 销售日期=cast(@sdate as datetime)
   union all
   select 销售日期 = dateadd(day, 1, 日期.销售日期) from 日期
   where 日期.销售日期<cast(@edate as datetime)
   ),
   销售 as (
   select 销售日期,SUM(销售金额) as 销售额 from 商品流水表
   group by 销售日期
   )
   
--通过”日期“的表左联连”销售“的表直接查询出我们要的数据
select a.销售日期,isnull(b.销售额,0) as 销售额 
from 日期 a Left Join 销售 b ON a.销售日期=b.销售日期

实现效果

上面可以看出用With As我们直接省去了一个临时表的创建,而且通过With As定义了一个SQL的片断,让我们代码的可读性更高了。

总的来说两种实现方式都可以,看个人喜欢,最终实现我们想要的目的才是重点。


-END-

Vaccae的往期经典


OpenCV

《C++ OpenCV案例实战---卡号获取

《C++ OpenCV案例实战---卡片截取(附代码)

《C++ OpenCV透视变换---切换手机正面图片》

《C++ OpenCV实战---获取数量

《C++ OpenCV实战---利用颜色分割获取数量》


Android

《Android利用SurfaceView结合科大讯飞修改语音实别UI

《Android关于语音识别的功能实现分析(一)---结构化思维》

《Android关于语音识别的功能实现分析(二)---语义解析》

《Android根据类生成签名字符串

《Android碎片化布局fragment的实战应用

《Android中RecyclerView嵌套RecyclerView

《Android里用AsyncTask后的接口回调


.Net C#

《C#自定义特性(Attribute)讲解与实际应用

《C#根据类生成签名字符串(附DEMO下载地址)

《C++创建动态库C#调用》

《C#与三菱PLC(型号FX2N)串口通讯类


数据库及其它

《Oracel存储过程写报表实战》

《Delphi轮播视频和图片程序(用于双屏显示程序)

《SQL随机增加销售数据的脚本编写(附脚本下载地址)

《Oracle通过ODBC连接SQL Server数据库


长按下方二维码关注微卡智享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vaccae

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值