加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQL查询 – 多列的SUM(CASE WHEN x THEN 1 ELSE 0)

发布时间:2020-12-12 16:25:44 所属栏目:MsSql教程 来源:网络整理
导读:我想看看下面的查询是否有更好的方法.我要做的是创建一个摘要报告,按日期编制统计数据. SELECT CAST(Detail.ReceiptDate AS DATE) AS 'DATE',SUM(CASE WHEN Detail.Type = 'TotalMailed' THEN 1 ELSE 0 END) AS 'TOTALMAILED',SUM(CASE WHEN Detail.Type = 'T
我想看看下面的查询是否有更好的方法.我要做的是创建一个摘要报告,按日期编制统计数据.
SELECT CAST(Detail.ReceiptDate AS DATE) AS 'DATE',SUM(CASE WHEN Detail.Type = 'TotalMailed' THEN 1 ELSE 0 END) AS 'TOTALMAILED',SUM(CASE WHEN Detail.Type = 'TotalReturnMail' THEN 1 ELSE 0 END) AS 'TOTALUNDELINOTICESRECEIVED',SUM(CASE WHEN Detail.Type = 'TraceReturnedMail' THEN 1 ELSE 0 END) AS 'TRACEUNDELNOTICESRECEIVED'
FROM
(
select SentDate AS 'ReceiptDate','TotalMailed' AS 'Type'
from MailDataExtract
where sentdate is not null
UNION ALL
select MDE.ReturnMailDate AS 'ReceiptDate','TotalReturnMail' AS 'Type'
from MailDataExtract MDE
where MDE.ReturnMailDate is not null
UNION ALL
select MDE.ReturnMailDate AS 'ReceiptDate','TraceReturnedMail' AS 'Type'
from MailDataExtract MDE
    inner join DTSharedData.dbo.ScanData SD ON SD.ScanDataID = MDE.ReturnScanDataID
where MDE.ReturnMailDate is not null AND SD.ReturnMailTypeID = 1
) AS Detail
GROUP BY CAST(Detail.ReceiptDate AS DATE)
ORDER BY 1

这只是查询的一个示例(在报告中使用),因为有许多其他列,而其他统计信息的逻辑则更复杂.是否有更优雅的方法来获取此类信息/撰写此类报告?

解决方法

我会通过以下方式更改查询:

>在子查询中进行聚合.这可以利用有关该表的更多信息来优化组.
>组合第二个和第三个子查询.它们聚合在同一列上.这需要使用左外连接以确保所有数据都可用.
>通过使用count(< fieldname>),您可以消除比较为null.这对于第二个和第三个计算值很重要.
>要组合第二个和第三个查询,需要计算mde表中的id.这些使用mde.mdeid.

以下版本使用union all跟随您的示例:

SELECT CAST(Detail.ReceiptDate AS DATE) AS "Date",SUM(TOTALMAILED) as TotalMailed,SUM(TOTALUNDELINOTICESRECEIVED) as TOTALUNDELINOTICESRECEIVED,SUM(TRACEUNDELNOTICESRECEIVED) as TRACEUNDELNOTICESRECEIVED
FROM ((select SentDate AS "ReceiptDate",COUNT(*) as TotalMailed,NULL as TOTALUNDELINOTICESRECEIVED,NULL as TRACEUNDELNOTICESRECEIVED
       from MailDataExtract
       where SentDate is not null
       group by SentDate
      ) union all
      (select MDE.ReturnMailDate AS ReceiptDate,COUNT(distinct mde.mdeid) as TOTALUNDELINOTICESRECEIVED,SUM(case when sd.ReturnMailTypeId = 1 then 1 else 0 end) as TRACEUNDELNOTICESRECEIVED
       from MailDataExtract MDE left outer join
            DTSharedData.dbo.ScanData SD
            ON SD.ScanDataID = MDE.ReturnScanDataID
       group by MDE.ReturnMailDate;
      )
     ) detail
GROUP BY CAST(Detail.ReceiptDate AS DATE)
ORDER BY 1;

以下使用完全外连接执行类似操作:

SELECT coalesce(sd.ReceiptDate,mde.ReceiptDate) AS "Date",sd.TotalMailed,mde.TOTALUNDELINOTICESRECEIVED,mde.TRACEUNDELNOTICESRECEIVED
FROM (select cast(SentDate as date) AS "ReceiptDate",COUNT(*) as TotalMailed
      from MailDataExtract
      where SentDate is not null
      group by cast(SentDate as date)
     ) sd full outer join
    (select cast(MDE.ReturnMailDate as date) AS ReceiptDate,COUNT(distinct mde.mdeID) as TOTALUNDELINOTICESRECEIVED,SUM(case when sd.ReturnMailTypeId = 1 then 1 else 0 end) as TRACEUNDELNOTICESRECEIVED
     from MailDataExtract MDE left outer join
          DTSharedData.dbo.ScanData SD
          ON SD.ScanDataID = MDE.ReturnScanDataID
     group by cast(MDE.ReturnMailDate as date)
    ) mde
    on sd.ReceiptDate = mde.ReceiptDate
ORDER BY 1;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读