在SQL中的GroupBy之后获取0计数的项目

时间:2015-06-23 10:58:57

标签: sql sql-server

我希望根据布尔值IsInsert获取过去5天的记录总数。以下查询忽略了总计的所有日期。

SELECT CAST(V.ChangeDate AS DATE) AS ChangeDate
    ,COUNT(*) AS Total
FROM CarrierRate.VendorBillUVBLog V WITH (NOLOCK)
WHERE V.IsInsert = 1
    AND v.ChangeDate >= DATEADD(d, - 4, GETDATE())
    AND v.ChangeDate <= GETDATE()
GROUP BY CAST(V.ChangeDate AS DATE)
ORDER BY CAST(V.ChangeDate AS DATE) DESC 

我已经检查过其他一些问题,但是当涉及到联接时它们都会解决。谢谢。

2 个答案:

答案 0 :(得分:1)

有时,解决此问题的最简单方法是使用条件聚合。如果您有所有日期的数据,但某些数据无法满足v.IsInsert = 1条件,那么这就足够了:

 SELECT CAST(V.ChangeDate AS DATE) AS ChangeDate, 
        SUM(CASE WHEN V.IsInsert = 1 THEN 1 ELSE 0 END) AS Total 
 FROM CarrierRate.VendorBillUVBLog V WITH(NOLOCK)    
 WHERE v.ChangeDate >= DATEADD(day, -4, GETDATE()) AND
       v.ChangeDate <= GETDATE()    
 GROUP BY CAST(V.ChangeDate AS DATE) 
 ORDER BY CAST(V.ChangeDate AS DATE) DESC ;

否则,您需要设置天数列表并使用:

with days as (
      select cast(getdate() as date) as dd union all
      select cast(getdate() - 1 as date) as dd union all
      select cast(getdate() - 2 as date) as dd union all
      select cast(getdate() - 3 as date) as dd union all
      select cast(getdate() - 4 as date) as dd 
     )
select d.dd, count(v.ChangeDate)
from days d left join
     CarrierRate.VendorBillUVBLog V WITH(NOLOCK)  
     on cast(v.ChangeDate as date) = d.dd
group by d.dd
order by d.dd;

答案 1 :(得分:1)

在Gordon的答案后半部分的基础上,您还需要将WHERE子句的条件添加到DaysVendorBillUVBLog之间的联接中。

with days as 
    (
      select cast(getdate() as date) as dd union all
      select cast(getdate() - 1 as date) as dd union all
      select cast(getdate() - 2 as date) as dd union all
      select cast(getdate() - 3 as date) as dd union all
      select cast(getdate() - 4 as date) as dd 
     )

select d.dd, count(v.ChangeDate)
from 
    days d 
     left join
    CarrierRate.VendorBillUVBLog V WITH(NOLOCK) on 
        cast(v.ChangeDate as date) = days.d AND
        V.IsInsert = 1  -- this line here needs to be part of the JOIN condition, not part of the WHERE
group by d.dd
order by d.dd;

您需要将其放在JOIN而不是WHERE中的原因是因为您希望从第一个表返回的所有日期是否在另一个表中存在任何有效行。

如果使用where子句添加过滤器,则实际上是在说&#34;从第一个表(Days)中检索所有行,从第二个表中检索所有行(VendorBill)。仅返回满足条件 x 。&#34;

的任一表中的行

由于您希望查看第一个表中的行,即使没有符合条件 x 的行,您也需要一个查询&#34;检索所有行的行第一张桌子(天)。还要从第二个表中返回符合 x 条件&#34;的任何行。如上所述,最好使用JOIN条件。