Reputation: 906
I want to group values and sum them up by a category value - or none. For example, I have the following table:
+-------+----------+
| value | category |
+-------+----------+
| 99 | A |
| 42 | A |
| 76 | [NULL] |
| 66 | B |
| 10 | C |
| 13 | [NULL] |
| 27 | C |
+-------+----------+
My desired result should look like this:
+-------+----------+
| sum | category |
+-------+----------+
| 230 | A |
| 155 | B |
| 126 | C |
| 89 | [NULL] |
+-------+----------+
I tried a group by category
but obviously this doesn't bring up the right numbers.
Any ideas?
I'm using SQL Server 2012.
EDIT: Ok, as requested, I can explain my intents and give my query so far, although that is not very helpful I think.
I need to sum all value for the given categories AND add the sum of all values without a category [=> NULL] So in my example, I would sum
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
I hope that gives you an idea of my goal.
Query so far:
SELECT SUM([value]), [category]
FROM [mytable]
GROUP BY [category]
Upvotes: 2
Views: 2263
Reputation: 45096
similar to levelonehuman put might be a little faster
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;
Upvotes: 0
Reputation: 1
Maybe you just missed using the SUM built-in function? This should work:
SELECT
SUM(value) AS [sum], category
FROM
[YourTableHere]
GROUP BY category
Edit: Ah, I see what you are doing now. I was able to do it by joining a 2nd query with just the NULL sum, so the NULL sum comes back with every row. Then you can just add it in the final step.
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
Upvotes: 0
Reputation: 35780
First calculate the sum of nulls then add it to each group:
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
Another version:
;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
Upvotes: 2
Reputation: 1505
You want to get the sum of the NULL
category and add it to the value of the other (non-null) categories:
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
This outputs
SumValue Category
89 NULL
230 A
155 B
126 C
Upvotes: 0
Reputation: 1269633
If you want to add the NULL
values to all the groups, then do something like:
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]'`?
This seems like a strange operation.
EDIT:
You can almost do this with window functions:
select category,
(sum(value) +
sum(case when category is null then sum(value) else 0 end) over ()
) as sumWithNulls
from t
group by category;
The problem is that NULL
s get over counted for that category. So:
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;
Upvotes: 0