2016-01-07 2 views
1

Я хочу сгруппировать значения и суммировать их по значению категории - или none. Например, у меня есть следующая таблица:GROUP BY с суммированием нулевых значений для каждой группы

+-------+----------+ 
| 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, но очевидно, что это не приносит вверх правильные цифры.

Любые идеи?

Я использую 2012

EDIT SQL Server: Ok, в соответствии с просьбой, я могу объяснить свои намерения и дать мой вопрос до сих пор, несмотря на то, что это не очень полезно, я думаю.

мне нужно суммировать все значения для данной категории и добавить сумму всех значений без категории [=> NULL] Таким образом, в моем примере, я бы просуммировать

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] 
+0

Можете ли вы показать ваш текущий запрос? – levelonehuman

+0

Почему «сумма», соответствующая категории «null», должна быть добавлена ​​ко всем суммам групп? –

ответ

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 
+0

Это выглядит довольно многообещающе. Я попробую сделать это в моем (на самом деле более сложном) запросе и отметить это как решение, если оно будет работать. +1 для примера для копирования/вставки. – z00l

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]'`? 

Это кажется странным операции.

EDIT:

Вы можете почти сделать это с оконными функциями:

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 s получить более подсчитаны для этой категории. Итак:

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; 
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 
0

Может быть, вы просто пропустили с помощью SUM встроенной функции? Это должно работать:

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

Редактировать: Ах, я вижу, что вы сейчас делаете. Я смог сделать это, присоединив второй запрос только с суммой NULL, поэтому сумма NULL возвращается с каждой строкой. Затем вы можете просто добавить его на последнем шаге.

SELECT 
MainSet.sum + JustNulls.sum AS [sum], MainSet.category 
FROM 

(SELECT SUM(X.value) AS [sum], X.category FROM [YourTableHere] X 
WHERE X.category IS NOT NULL GROUP BY category 
UNION SELECT 0, NULL) MainSet 

FULL JOIN 

(SELECT SUM(Y.value) AS [sum], Y.category FROM [YourTableHere] Y 
WHERE Y.category IS NULL GROUP BY category) JustNulls ON 1=1 
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; 
Смежные вопросы