Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询-多列的求和(当x为1时为1,否则为0时为1)_Sql - Fatal编程技术网

SQL查询-多列的求和(当x为1时为1,否则为0时为1)

SQL查询-多列的求和(当x为1时为1,否则为0时为1),sql,Sql,我想看看是否有更好的方法来处理下面的查询。我要做的是创建一个摘要报告,按日期编译统计数据 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 'TOT

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

 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   

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

我认为您应该使用子查询来进行分组。在这种情况下,内部子查询返回很少的行,并且不需要case语句。所以我认为这会更快:

select Detail.ReceiptDate AS 'DATE',
       SUM(TotalMailed),
       SUM(TotalReturnMail),
       SUM(TraceReturnedMail)

from
(

select SentDate AS 'ReceiptDate', 
       count('TotalMailed') AS TotalMailed, 
       0 as TotalReturnMail, 
       0 as TraceReturnedMail
from MailDataExtract
where sentdate is not null
GROUP BY SentDate

UNION ALL
select MDE.ReturnMailDate AS 'ReceiptDate', 
       0 AS TotalMailed, 
       count(TotalReturnMail) as TotalReturnMail, 
       0 as TraceReturnedMail
from MailDataExtract MDE
where MDE.ReturnMailDate is not null
GROUP BY  MDE.ReturnMailDate

UNION ALL

select MDE.ReturnMailDate AS 'ReceiptDate', 
       0 AS TotalMailed, 
       0 as TotalReturnMail, 
       count(TraceReturnedMail) as TraceReturnedMail

from MailDataExtract MDE
    inner join DTSharedData.dbo.ScanData SD 
        ON SD.ScanDataID = MDE.ReturnScanDataID
   where MDE.ReturnMailDate is not null AND SD.ReturnMailTypeID = 1
GROUP BY MDE.ReturnMailDate

) as Detail
GROUP BY Detail.ReceiptDate
ORDER BY 1

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

  • 在子查询中执行聚合。这可以利用有关表的更多信息来优化
    分组依据
  • 合并第二个子查询和第三个子查询。它们聚集在同一列上。这需要使用
    左外部联接
    ,以确保所有数据可用
  • 通过使用
    count()。这对于第二个和第三个计算值很重要
  • 要组合第二个和第三个查询,它需要从
    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;
    
    下面使用
    完全外部联接执行类似操作:

    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;
    

    这是在进程或视图中,还是在其他地方?基本上,您可以引入变量并运行多个语句,或者它只是一个大的
    select
    语句吗?它是一个用于SSRS报告的过程,因此它本质上需要是一个select语句,因为我需要返回一个结果集(对吗?)是的,您最终会得到一个大的
    select
    ,但由于它在一个过程中,您将能够将查询分解为更小、更简单的块,并在执行过程中为变量赋值。这在可读性方面会有很大的不同。例如,您可以提前运行三个小型独立查询,将汇总结果分配给变量,然后只需为返回查询选择这些变量,而不必对这三个子查询进行
    union
    ing或分组。可能更容易阅读和理解,也可能表现得更好。