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'
我正在尝试创建一个 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'