SELECT CASE 语句,当没有行匹配 case 时,COUNT(*) 聚合以包含 0

问题描述 投票:0回答:4

我想要一个包含所有类别及其计数的结果集,即使一个或多个计数为 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

错了

sql sql-server count case aggregate-functions
4个回答
0
投票

这可能是一个选项:

  • 对每个条件进行查询,并使用“UNION ALL”键合并查询,以便将查询结果混合在一个结果中。

查询:

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 上工作。


0
投票

你可以先写条件(用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

演示


0
投票

另一种方法是通过

  • 将您的符号字符串值与您的表交叉连接
  • 根据所需符号有条件地计算您的值
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

在这里查看演示.


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

这应该可以工作,但我还没有测试过。由于您需要所有符号值,因此您需要一个包含所有符号值的表格。您可以像上面那样执行表值子查询,也可以执行实际或临时表。但想法是,如果您的数据中不存在该值,您将不会在输出中获得它。由于这两个值都不在您的数据中,因此您需要创建一个包含它的表。然后我们根据数字的符号连接到您的实际表格并进行计数。

编辑:从计数方法更改为求和以说明连接中丢失的行

© www.soinside.com 2019 - 2024. All rights reserved.