我想要一个包含所有类别及其计数的结果集,即使一个或多个计数为 0。
桌子:
Numbers
id | 数字 |
---|---|
0 | 2 |
1 | -1 |
2 | 1 |
我试过的:
SELECT sign,
COUNT(*) sign_count
FROM (SELECT CASE WHEN number < 0 THEN 'negative'
WHEN number > 0 THEN 'positive'
ELSE 'neither'
END AS sign
FROM Numbers) n
GROUP BY sign
我得到的:
标志 | sign_count |
---|---|
负面 | 1 |
正面 | 2 |
我想要的:
标志 | sign_count |
---|---|
负面 | 1 |
都不是 | 0 |
正面 | 2 |
我知道
Numbers
中的值都不对应于 neither
,但是我如何按空类别分组?我也四处搜索并尝试在 id 列上使用 Numbers
进行自我连接,并创建了一个单独的 Signs
表,其中包含所有三个标志以执行外部连接,但都没有给出我正在寻找的东西。
@艾哈迈德 表:
Signs
标志 |
---|
负面 |
都不是 |
正面 |
包含左连接的查询:
SELECT s.sign,
COUNT(*) sign_count
FROM (SELECT CASE WHEN number < 0 THEN 'negative'
WHEN number > 0 THEN 'positive'
ELSE 'neither'
END AS sign
FROM Numbers) n
LEFT JOIN Signs s ON n.sign = s.sign
GROUP BY s.sign
以上结果:
标志 | sign_count |
---|---|
负面 | 1 |
正面 | 2 |
如果在查询中将
LEFT
替换为RIGHT
,结果:
标志 | sign_count |
---|---|
负面 | 1 |
都不是 | 1 |
正面 | 2 |
错了
这可能是一个选项:
查询:
SELECT 'negative' sign, COUNT(1) sign_count
FROM Numbers
WHERE number < 0
UNION ALL
SELECT 'neither' sign, COUNT(1) sign_count
FROM Numbers
WHERE number = 0
UNION ALL
SELECT 'positive' sign, COUNT(1) sign_count
FROM Numbers
WHERE number > 0;
结果:
标志 | sign_count |
---|---|
负面 | 1 |
都不是 | 0 |
正面 | 2 |
看到它在 sqlfiddle 上工作。
你可以先写条件(用cte)然后根据这些条件分组
with _listcon as (
select 'negative' as sign,CAST(0x8000000000000000 AS bigint) /*min bigint*/ startNumber,-1 EndNumber union
select 'positive' as sign,1 startNumber, CAST(0x7FFFFFFFFFFFFFFF AS bigint) /*max bigint*/ EndNumber union
select 'neither' as sign, 0 startNumber,0 EndNumber
)
select sign, ISNULL( COUNT(a.number),0) sign_count
from Numbers a
right join _listcon b on a.number between startNumber and EndNumber
GROUP BY sign
另一种方法是通过
SELECT sign,
COUNT(CASE WHEN sign = 'positive' AND number > 0 THEN 1
WHEN sign = 'negative' AND number < 0 THEN 1
WHEN sign = 'neither' AND number = 0 THEN 1 END) AS sign_count
FROM (VALUES('positive'),('negative'),('neither')) AS signs(sign)
CROSS JOIN Numbers
GROUP BY sign
输出:
标志 | sign_count |
---|---|
正面 | 2 |
负面 | 1 |
都不是 | 0 |
在这里查看演示.
SELECT signs.sign,
SUM(CASE WHEN Numbers.number IS NULL THEN 0 ELSE 1 END)
FROM (SELECT 'positive' AS [sign]
UNION ALL
SELECT 'negative'
UNION ALL
SELECT 'neither') AS signs
LEFT OUTER JOIN Numbers
ON (signs.sign = CASE WHEN number < 0 THEN 'negative'
WHEN number > 0 THEN 'positive'
ELSE 'neither' END)
GROUP BY signs.sign
这应该可以工作,但我还没有测试过。由于您需要所有符号值,因此您需要一个包含所有符号值的表格。您可以像上面那样执行表值子查询,也可以执行实际或临时表。但想法是,如果您的数据中不存在该值,您将不会在输出中获得它。由于这两个值都不在您的数据中,因此您需要创建一个包含它的表。然后我们根据数字的符号连接到您的实际表格并进行计数。
编辑:从计数方法更改为求和以说明连接中丢失的行