【问题标题】:Count rows for two columns using two different clauses使用两个不同的子句计算两列的行数
【发布时间】:2015-09-01 04:59:47
【问题描述】:
我想要返回两列的 CTE,一列包含 1 的总数,另一列包含 0 的总数。目前我可以让它返回一列,其中 1 的总数使用:
WITH getOnesAndZerosCTE
AS (
SELECT COUNT([message]) AS TotalNo1s
FROM dbo.post
WHERE dbo.checkletters([message]) = 1
--SELECT COUNT([message]) AS TotalNo0s
--FROM dbo.post
--WHERE dbo.checkletters([message]) = 0
)
SELECT * FROM getOnesAndZerosCTE;
我如何在同一个 CTE 中有第二列称为 TotalNo0s,我在其中发表了评论以说明我的意思。
【问题讨论】:
标签:
sql
sql-server
common-table-expression
【解决方案1】:
使用条件聚合:
WITH getOnesAndZerosCTE AS(
SELECT
TotalNo1s = SUM(CASE WHEN dbo.checkletters([message]) = 1 THEN 1 ELSE 0 END),
TotalNo0s = SUM(CASE WHEN dbo.checkletters([message]) = 0 THEN 1 ELSE 0 END)
FROM post
)
SELECT * FROM getOnesAndZerosCTE;
【解决方案2】:
对于直接使用 COUNT() ,请注意它会计算任何非空值。您可以省略 ELSE 条件,如果未声明则隐式返回 NULL
SELECT
COUNT(CASE WHEN dbo.checkletters([message]) = 1 THEN 1 END) TotalNo1s
, COUNT(CASE WHEN dbo.checkletters([message]) = 0 THEN 1 END) TotalNo0s
FROM post
或者,明确声明 NULL
SELECT
COUNT(CASE WHEN dbo.checkletters([message]) = 1 THEN 1 ELSE NULL END) TotalNo1s
, COUNT(CASE WHEN dbo.checkletters([message]) = 0 THEN 1 ELSE NULL END) TotalNo0s
FROM post
【解决方案3】:
没有 CTE 也可以做到
select count(message) total,
dbo.checkletters(message) strLength
from post
group by dbo.checkletters(message)
having dbo.checkletters(message) in (1, 2) //All the messages with length 1 or 2