This is my table in SQL Server :
number grade weight -------------------------- 1 A 185 2 A 179 3 C 191 4 C 192 5 C 193 6 A 194 7 A 196 8 A 188 9 A 187 10 A 200 11 B 201 12 B 202 13 B 203 14 B 191 15 B 187
and I want this output in SQL Server (return this Text with Query not function):
Count of A : 7 , Sum of A : 1329 - Count of B : 5 , Sum of B : 984 - Count of C : 3 , Sum of C : 576
Does anyone know how I can do this?
Advertisement
Answer
Modern Versions
If on SQL Server 2017 or better, you can also do it this way (and this prevents you from having to know in advance and hard-code all the possible grades A
, B
, C
etc., which makes it harder to add D
, E
, and so on later):
;WITH x AS ( SELECT g = grade, y = CONCAT('Count$g', COUNT(*), ' , Sum$g', SUM(weight)) FROM dbo.TableName GROUP BY grade ) SELECT STRING_AGG(REPLACE(y,'$g',' of ' + g + ' : '),' - ') WITHIN GROUP (ORDER BY g) FROM x;
Output
Count of A : 7 , Sum of A : 1329 – Count of B : 5 , Sum of B : 984 – Count of C : 3 , Sum of C : 576
2012, 2014, 2016
If on 2012 – 2016, you can’t use STRING_AGG()
, but you can use FOR XML PATH
to achieve the same thing:
;WITH x AS ( SELECT g = grade, y = CONCAT('Count$g', COUNT(*), ' , Sum$g', SUM(weight)) FROM dbo.TableName GROUP BY grade ) SELECT STUFF(( SELECT ' - ' + REPLACE(y, '$g', ' of ' + g + ' : ') FROM x ORDER BY g FOR XML PATH(''), TYPE).value(N'./text()[1]', N'varchar(max)'), 1, 3, '');
2005, 2008, 2008 R2
If you’re on earlier (unsupported and ill-advised) versions (2005 – 2008 R2), you’ll just have to make changes to the latter to perform manual string concatenations (and data type handling) instead of using CONCAT()
.
;WITH x AS ( SELECT g = grade, y = 'Count$g' + CONVERT(varchar(11), COUNT(*)) + ' , Sum$g' + CONVERT(varchar(11), SUM(weight)) FROM dbo.TableName GROUP BY grade ) SELECT STUFF(( SELECT ' - ' + REPLACE(y, '$g', ' of ' + g + ' : ') FROM x ORDER BY g FOR XML PATH(''), TYPE).value(N'./text()[1]', N'varchar(max)'), 1, 3, '');