SQL Server group by absorb null and empty values

核能气质少年 提交于 2021-01-28 00:02:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!