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

前端之家收集整理的这篇文章主要介绍了SQL查询 – 多列的SUM(CASE WHEN x THEN 1 ELSE 0)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想看看下面的查询是否有更好的方法.我要做的是创建一个摘要报告,按日期编制统计数据.
  1. 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'
  2. FROM
  3. (
  4. select SentDate AS 'ReceiptDate','TotalMailed' AS 'Type'
  5. from MailDataExtract
  6. where sentdate is not null
  7. UNION ALL
  8. select MDE.ReturnMailDate AS 'ReceiptDate','TotalReturnMail' AS 'Type'
  9. from MailDataExtract MDE
  10. where MDE.ReturnMailDate is not null
  11. UNION ALL
  12. select MDE.ReturnMailDate AS 'ReceiptDate','TraceReturnedMail' AS 'Type'
  13. from MailDataExtract MDE
  14. inner join DTSharedData.dbo.ScanData SD ON SD.ScanDataID = MDE.ReturnScanDataID
  15. where MDE.ReturnMailDate is not null AND SD.ReturnMailTypeID = 1
  16. ) AS Detail
  17. GROUP BY CAST(Detail.ReceiptDate AS DATE)
  18. ORDER BY 1

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

解决方法

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

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

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

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

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

  1. SELECT coalesce(sd.ReceiptDate,mde.ReceiptDate) AS "Date",sd.TotalMailed,mde.TOTALUNDELINOTICESRECEIVED,mde.TRACEUNDELNOTICESRECEIVED
  2. FROM (select cast(SentDate as date) AS "ReceiptDate",COUNT(*) as TotalMailed
  3. from MailDataExtract
  4. where SentDate is not null
  5. group by cast(SentDate as date)
  6. ) sd full outer join
  7. (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
  8. from MailDataExtract MDE left outer join
  9. DTSharedData.dbo.ScanData SD
  10. ON SD.ScanDataID = MDE.ReturnScanDataID
  11. group by cast(MDE.ReturnMailDate as date)
  12. ) mde
  13. on sd.ReceiptDate = mde.ReceiptDate
  14. ORDER BY 1;

猜你在找的MsSQL相关文章