当前位置: 首页 > 面试题库 >

SQL查询-多列的SUM(WHEN x THEN 1 ELSE 0的情况)

佴涵蓄
2023-03-14
问题内容

我想看看下面是否有更好的查询方法。我想做的是创建一个摘要报告,按日期编译统计信息。

 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

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


问题答案:

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

  1. 在子查询中进行聚合。这样可以利用有关表格的更多信息来优化group by
  2. 合并第二个和第三个子查询。它们聚集在同一列上。这需要使用left outer join来确保所有数据都可用。
  3. 通过使用,count(<fieldname>)您可以消除与的比较is null。这对于第二和第三计算值很重要。
  4. 要组合第二个查询和第三个查询,它需要从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, 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;

以下使用做了类似的事情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;


 类似资料:
  • 我有两个表:包含5列(col1、col2、col3、col4、val1)的表1和包含5列(col1、col2、col3、col4、val2)的表2。1.表1.val1不包含任何值。2.对于表1和表2来说,col1、col2、col3和col4是相同的,它们是主键。 我想做的是,当table1.col1=table2.col1和table1.col2=table2.col2和table1.col3=

  • 问题内容: 如果我在SQL Server Express 2008上运行此查询: 它将日期存储为2011年4月11日 我该如何预防呢? 问题答案: 使用ISO-8601格式:(或)-无论您使用哪种SQL Server语言和区域设置,它始终有效。 SQL Server中的日期 不 以任何特定的面向字符串的格式存储-日期即是日期即是日期,无论您看到什么。 您会看到日期的字符串表示形式-但又一次:日期

  • 例如,我在MongoDB中有以下数据: 现在我想查询“SUM传入的数量在11 - 12之间”(结果应该是500),我如何使用Mongo Shell来做到这一点?

  • 问题内容: 我需要一个SQL查询来从消息队列中选择行,直到SUM(users_count)最多达到1000。 但是 ,如果仅返回一行并且该行的users_count大于1000,就没有问题。 我需要类似的内容:(我添加了自己的关键字) 这是我的表结构: messages_queue -msg_id -msg_body-users_count (消息接收方的数量) -时间(插入时间) 问题答案: 该

  • 问题内容: 我正在使用iReport创建JasperReport,因此,我仅限于*一个SQL查询。 我有一个表“ statistics”,其中有一个“名称”(VARCHAR),“计数”(INTEGER)和“日期时间”(DATETIME)列。 当“名称”在最后一天(同样是最后一周和一个月)进行“测试”时,获取“计数”列的总和非常简单。 工作的SQL语句: 但是,由于我只有一个SQL语句可以使用,因此

  • 我有一张学生记分卡表。这是表格, 现在,我需要对每个学生的总分求和。我通过使用< code>sum(mark1 mark2...markn)按stud分组。我想知道如何在不添加每个列名的情况下对其求和,如果达到marks26,这将是巨大的。有人知道如何修理它吗?提前感谢。