我想看看下面的查询是否有更好的方法.我要做的是创建一个摘要报告,按日期编制统计数据.
- 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;