I'm looking to see if there is a better approach to the query below. What I'm trying to do is create a summary report, compiling stats by date.
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
This is only a sample of the query (which is used in a report) as there are a number of other columns and the logic for the other stats are way more complicated. Is there a more elegant approach to getting this kind of information/writing this kind of report?
I would change the query in the following ways:
group by
.left outer join
to ensure that all data is available.count(<fieldname>)
you can eliminate the comparisons to is null
. This is important for the second and third calculated values.mde
table. These use mde.mdeid
.The following version follows your example by using 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, 0,
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;
The following does something similar using full outer join
:
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With