Case 语句忽略 where 子句

Case statement is ignoring where clause

我正在尝试创建一个 SQL 声明 returns 多个计数。下面的计数符合我的预期,但 case 语句忽略了我的查询的 where 子句。

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

*edit 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

我建议您使用标准日期格式。大多数数据库支持 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;

日期比较可能真的是作为字符串进行的,所以它们没有按照您的预期进行。

我怀疑您得到的 othercount 的数字可能比预期的要高,但这可能是由于使用 count(distinct...) 减少了第一列的结果,但没有减少第二列的结果。也许将子查询引入 select 只有不同的值会有所帮助?

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。同样,使用 between 不是日期范围的最佳做法,我们鼓励您改用 >=<,如下所示:

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'