Case语句忽略where子句

时间:2018-01-15 22:51:58

标签: sql sql-server tsql case-when

我正在尝试创建一个返回多个计数的SQL语句。下面的计数按预期工作,但case语句忽略了我的查询的where子句。

我正在尝试获得满足where条件的PacketId的总数。然后获得第二个总数,显示满足where条件并且StatusId为3的PacketId的总和。

*编辑Table1和Table2都将PacketId作为外键共享。

Select 
Count(Distinct wpq.PacketId) AS Total,
SUM(Case When wpq.StatusId = 3 THEN 1 ELSE 0 END) as OtherCount
FROM [Table1] ppo JOIN [Table2] wpq ON ppo.PacketId = wpq.PacketId
WHERE wpq.CreateDate between  '11/1/2017' and '1/1/2018' and ppo.IsSelected = 1

2 个答案:

答案 0 :(得分:1)

我怀疑你可能会获得比othercount更高的数字,但这可能是由于使用count(distinct...)会减少第一列结果,但不是第二列结果。也许引入子查询只选择不同的值会有帮助吗?

SELECT DISTINCT
      wpq.PacketId
    , wpq.StatusId
FROM [Table1] ppo
JOIN [Table2] wpq ON ppo.PacketId = wpq.PacketId
WHERE wpq.CreateDate BETWEEN '11/1/2017' AND '1/1/2018'
AND ppo.IsSelected = 1
;

然后从那里算起来,例如:

SELECT
      COUNT(PacketId)                                 AS total
    , COUNT(CASE WHEN StatusId = 3 THEN StatusId END) AS othercount
    , SUM(CASE WHEN StatusId = 3 THEN 1 ELSE 0 END)   AS othersum
FROM (
      SELECT DISTINCT
            wpq.PacketId
          , wpq.StatusId
      FROM [Table1] ppo
      JOIN [Table2] wpq ON ppo.PacketId = wpq.PacketId
      WHERE wpq.CreateDate BETWEEN '11/1/2017' AND '1/1/2018'
      AND ppo.IsSelected = 1
      ) AS d
;

注意:COUNT()函数忽略空值,因此我添加了另一种要考虑的计算方法。我更喜欢在这样的查询中使用COUNT()

另外我想请注意,您使用看似M / D / YYYY日期文字的内容并不安全。 T-SQL中最安全的日期文字格式是YYYYMMDD。同样地,使用两者之间并不是日期范围的最佳做法,wpuld鼓励您使用>=<,如下所示:

SELECT
      COUNT(PacketId)                                 AS total
    , COUNT(CASE WHEN StatusId = 3 THEN StatusId END) AS othercount
    , SUM(CASE WHEN StatusId = 3 THEN 1 ELSE 0 END)   AS othersum
FROM (
      SELECT DISTINCT
            wpq.PacketId
          , wpq.StatusId
      FROM [Table1] ppo
      JOIN [Table2] wpq ON ppo.PacketId = wpq.PacketId
      WHERE wpq.CreateDate >= '20171101' AND wpq.CreateDate < '20180101'
      AND ppo.IsSelected = 1
      ) AS d
;

注意我不确定您是否确实要包括1/1/2018,如果您确实要使用< '20180102'而不是

答案 1 :(得分:0)

我建议您使用标准日期格式。大多数数据库支持YYYY-MM-DD:

SELECT COUNT(DISTINCT wpq.PacketId) AS Total,
       SUM(Case When wpq.StatusId = 3 THEN 1 ELSE 0 END) as OtherCount
FROM [Table1] ppo JOIN
     [Table2] wpq
     ON ppo.PacketId = wpq.PacketId
WHERE wpq.CreateDate >= '2017-11-01' AND
      wpq.CreateDate <= '2018-01-01' AND
      ppo.IsSelected = 1;

日期比较可能是以字符串形式完成的,所以它们没有达到预期的效果。