问题
I have this data:
Id Name amount Comments
-------------------------------
1 n1 421762 Hello
2 n2 421 Bye
3 n2 262 null
4 n2 5127 ''
Each name may or may not have extra rows with null or empty comments.
How can I group by name and sum(amount) such that it ignores/absorbs the null or empty comments in the grouping and shows me only 2 groups.
Output I want:
Id Name sum(amount) Comments
------------------------------------
1 n1 421762 Hello
2 n2 5180 Bye
I can't figure this out.
I hoped that would ignore the null/empty values but I always end up with 4 groups
select id, name, sum(amount), comments
from table
group by id, name, comments
回答1:
You can't have a field in the SELECT
statement unless it's part of the GROUP BY clause or used for aggregation. The question and desired output shows that the rows should be grouped by name, which means all other fields (ID,amount, comments) should be aggregated.
The question doesn't specify how the IDs should be aggregated, or which comments should appear. Aggregating strings is only possible using functions like MIN/MAX in all SQL Server versions up to 2016. SQL Server 2017 added STRING_AGG to concatenate strings. In earlier versions people have to use one of many string aggregation techniques that may involve XML or SQLCLR functions.
In SQL Server versions the desired output can be produced by
SELECT MIN(ID) as ID,name,sum(amount) as Amount, max(comment) as comments
from #table1
group by name
This produces the desired output :
ID name Amount comments
1 n1 421762 Hello
2 n2 5810 Bye
This assumes that there is only one non-empty comment. The question doesn't specify something different though.
In SQL Server 2017 multiple comments can be concatenated with STRING_AGG :
SELECT MIN(ID) as ID,name,sum(amount) as Amount, STRING_AGG(comment,' ') as comments
from table1
group by name
Given the question's data, this will also produce the desired output.
ID name Amount comments
1 n1 421762 Hello
2 n2 5810 Bye
回答2:
Just use MAX()
with comments
:
select id, name, sum(amount), MAX(comments)
from table
group by id, name;
回答3:
Select Top 1 with Ties
ID
,Name
,Amount = sum(Amount) over (Partition By Name)
,Comments = max(Comments) over (Partition By Name)
from YourTable
Order by Row_Number() over (Partition By Name Order by ID)
Returns
ID Name Amount Comments
1 n1 421762 Hello
2 n2 5810 Bye
回答4:
use row_number()
select id,name,comments,amount from
(select id,name,
row_number() over(partition by Name order by case when Comments is not null then 1 else 2 end) rn,
sum(amount) over(partition by Name) as amount,comments
from table_name
) a where a.rn=1
来源:https://stackoverflow.com/questions/55027780/sql-server-group-by-absorb-null-and-empty-values