GROUP BY将空值汇总到每个组

时间:2016-01-07 17:06:15

标签: sql sql-server tsql sql-server-2012

我想对值进行分组并按类别值进行总结 - 或者没有。 例如,我有下表:

+-------+----------+
| value | category |
+-------+----------+
|    99 |        A |
|    42 |        A |
|    76 |   [NULL] |
|    66 |        B |
|    10 |        C |
|    13 |   [NULL] |
|    27 |        C |
+-------+----------+

我想要的结果应该是这样的:

+-------+----------+
|   sum | category |
+-------+----------+
|   230 |        A |
|   155 |        B |
|   126 |        C |
|    89 |   [NULL] |
+-------+----------+

我尝试了group by category,但显然这并没有提出正确的数字。

有什么想法吗?

我正在使用SQL Server 2012。

编辑: 好的,根据要求,我可以解释我的意图并提供我的查询到目前为止,虽然这对我认为不是很有帮助。

我需要对给定类别的所有值求和并添加所有值的总和而不使用类别[=>空值] 所以在我的例子中,我会求和

99 + 42 + 76 + 13 = 230 for category A
66 + 76 + 13 = 155      for category B
10 + 27 + 76 + 13 = 126 for category C
76 + 13 = 89            for no category

我希望能让你了解我的目标。

到目前为止的查询:

SELECT SUM([value]), [category]
FROM [mytable]
GROUP BY [category]

5 个答案:

答案 0 :(得分:2)

首先计算空值之和,然后将其添加到每个组:

DECLARE @t TABLE
    (
      value INT ,
      category CHAR(1)
    )

INSERT  INTO @t
VALUES  ( 99, 'A' ),
        ( 42, 'A' ),
        ( 76, NULL ),
        ( 66, 'B' ),
        ( 10, 'C' ),
        ( 13, NULL ),
        ( 27, 'C' )

;with cte as(select sum(value) as s from @t where category is null)
select category, sum(value) + s 
from @t
cross join cte
where category is not null
group by category, s

另一个版本:

;WITH cte AS(SELECT category, SUM(value) OVER(PARTITION BY category) + 
                 SUM(CASE WHEN category IS NULL THEN value ELSE 0 END) OVER() AS value 
             FROM @t)
SELECT DISTINCT * FROM cte WHERE category IS NOT NULL

答案 1 :(得分:0)

如果要将NULL值添加到所有组,请执行以下操作:

with cte as (
      select category, sum(value) as sumv
      from t
      group by category
     )
select cte.category,
       (cte.sumv +
        (case when category is not null then coalesce(ctenull.sumv) else 0 end)
       ) as sumWithNulls
from cte left join
     cte ctenull
     on ctenull.category is null     -- or should that be `= '[NULL]'`?

这似乎是一个奇怪的操作。

编辑:

您几乎可以使用窗口函数执行此操作:

select category,
       (sum(value) +
        sum(case when category is null then sum(value) else 0 end) over ()
       ) as sumWithNulls
from t
group by category;

问题在于NULL已经过了该类别的计算。所以:

select category,
       (sum(value) +
        (case when category is not null
              then sum(case when category is null then sum(value) else 0 end) over ()
              else 0
        end
       ) as sumWithNulls
from t
group by category;

答案 2 :(得分:0)

您希望获得NULL类别的总和,并将其添加到其他(非空)类别的值中:

DECLARE @Table1 TABLE (Value int, Category varchar(1))

DECLARE @NullCategorySum int

INSERT INTO @Table1
    (Value, Category)
VALUES
    (99, 'A'),
    (42, 'A'),
    (76, NULL),
    (66, 'B'),
    (10, 'C'),
    (13, NULL),
    (27, 'C')

SELECT  @NullCategorySum = SUM(Value)
FROM    @Table1
WHERE   Category IS NULL

SELECT  SUM(t1.Value) 
            + CASE  
                WHEN Category IS NOT NULL THEN @NullCategorySum 
              END 
        AS SumValue, Category
FROM    @Table1 t1
GROUP BY Category 

此输出

SumValue    Category
89          NULL
230         A
155         B
126         C

答案 3 :(得分:0)

也许您只是错过了使用SUM内置函数?这应该有效:

var setting = ReadConfigurationFile("a", "b", "c", "d") ?? "some default value";
编辑:啊,我明白你现在在做什么。我能够通过仅使用NULL总和加入第二个查询来完成它,因此每行返回NULL总和。然后你可以在最后一步中添加它。

SELECT
SUM(value) AS [sum], category
FROM
[YourTableHere]
GROUP BY category

答案 4 :(得分:0)

类似于levelonehuman,可能更快一点

declare @countNull int = (select sum(textUniqueWordCount) from docSVsys where  mimeType is null);
select mimeType, sum(isnull(textUniqueWordCount, 0)) + @countNull  as [sum]  
from docSVsys 
where mimeType is not null
group by mimeType
union 
select null, @countNull;