如何使用 STRING_AGG() 以升序分隔字符串逗号
How to get strings comma separated in ascending order with STRING_AGG()
我的table看起来像这样
Color Order
------------
Red 49
Blue 32
Green 80
Green 30
Blue 93
Blue 77
Red 20
Green 54
Red 59
Red 42
Red 81
Green 35
Blue 91
我的查询是
SELECT Color, Count(*) AS Count, STRING_AGG(Order,',') AS AggOrder
FROM MyTable
GROUP BY Color
当我按颜色分组并聚合时,我得到未排序的订单
像这样
Color Count AggOrder
------------------------------
Red 5 49,20,59,42,81
Blue 4 32,93,77,91
Green 4 80,30,54,35
问题:
AggOrder 是无序的
49,20,59,42,81
我要订
所以最后的结果是
Color Count AggOrder
------------------------------
Red 5 20,42,49,59,81
Blue 4 32,77,91,93
Green 4 30,35,54,80
我试过这个查询
SELECT Color, Count(*) AS Count, STRING_AGG(Order,',') AS AggOrder
FROM MyTable
GROUP BY Color
ORDER BY Order
但这给出了一个错误。
知道如何解决这个问题吗?
您可以使用 within group
语法
SELECT Color
, Count(*) AS Count
, STRING_AGG([Order],',') WITHIN GROUP (ORDER BY [Order]) AS AggOrder
FROM MyTable
GROUP BY Color
在您对 STRING_AGG
的调用中添加一个 ORDER BY
子句:
SELECT
Color,
COUNT(*) AS Count,
STRING_AGG([Order], ',') WITHIN GROUP (ORDER BY CAST([Order] AS INT)) AS AggOrder
FROM MyTable
GROUP BY Color;
Order
列有两条评论。首先,ORDER
是保留的 SQL 服务器关键字,您在问题中粘贴的查询甚至不会 运行 作为给定的,因为 ORDER
当用作数据库对象时名称需要转义。您应该避免使用关键字命名您的列、表等。其次,假设 Order
列是文本,如果你想用它作为数字来排序,你应该首先转换为整数。
对于SQL Server 2017 或更高版本那么你已经得到了答案。但是如果 SQL 服务器比 2017 年旧,你可以使用 stuff() 和 XML PATH FOR() 来获得你想要的结果:
由于您使用的是 SQL Server 2017 或更高版本,请不要使用此解决方案,而应使用带有 string_agg() 的解决方案,因为该解决方案更快且易于实施。
架构:
create table MyTable (color varchar(10), [order] int);
insert into MyTable values('Red', 49);
insert into MyTable values('Blue', 32);
insert into MyTable values('Green', 80);
insert into MyTable values('Green', 30);
insert into MyTable values('Blue', 93);
insert into MyTable values('Blue', 77);
insert into MyTable values('Red', 20);
insert into MyTable values('Green', 54);
insert into MyTable values('Red', 59);
insert into MyTable values('Red', 42);
insert into MyTable values('Red', 81);
insert into MyTable values('Green', 35);
insert into MyTable values('Blue', 91);
查询:
SELECT color,count(*) [Count],
STUFF((SELECT ',' + COALESCE(LTRIM(RTRIM([order])), '')
FROM MyTable mt
WHERE mt.color = m.color
order by [order]
FOR XML PATH('') ), 1, 1, ''
) as AggOrder
FROM MyTable m
group by color
输出:
color
Count
AggOrder
Blue
4
32,77,91,93
Green
4
30,35,54,80
Red
5
20,42,49,59,81
db<>fiddle here
我的table看起来像这样
Color Order
------------
Red 49
Blue 32
Green 80
Green 30
Blue 93
Blue 77
Red 20
Green 54
Red 59
Red 42
Red 81
Green 35
Blue 91
我的查询是
SELECT Color, Count(*) AS Count, STRING_AGG(Order,',') AS AggOrder
FROM MyTable
GROUP BY Color
当我按颜色分组并聚合时,我得到未排序的订单
像这样
Color Count AggOrder
------------------------------
Red 5 49,20,59,42,81
Blue 4 32,93,77,91
Green 4 80,30,54,35
问题: AggOrder 是无序的 49,20,59,42,81
我要订
所以最后的结果是
Color Count AggOrder
------------------------------
Red 5 20,42,49,59,81
Blue 4 32,77,91,93
Green 4 30,35,54,80
我试过这个查询
SELECT Color, Count(*) AS Count, STRING_AGG(Order,',') AS AggOrder
FROM MyTable
GROUP BY Color
ORDER BY Order
但这给出了一个错误。
知道如何解决这个问题吗?
您可以使用 within group
语法
SELECT Color
, Count(*) AS Count
, STRING_AGG([Order],',') WITHIN GROUP (ORDER BY [Order]) AS AggOrder
FROM MyTable
GROUP BY Color
在您对 STRING_AGG
的调用中添加一个 ORDER BY
子句:
SELECT
Color,
COUNT(*) AS Count,
STRING_AGG([Order], ',') WITHIN GROUP (ORDER BY CAST([Order] AS INT)) AS AggOrder
FROM MyTable
GROUP BY Color;
Order
列有两条评论。首先,ORDER
是保留的 SQL 服务器关键字,您在问题中粘贴的查询甚至不会 运行 作为给定的,因为 ORDER
当用作数据库对象时名称需要转义。您应该避免使用关键字命名您的列、表等。其次,假设 Order
列是文本,如果你想用它作为数字来排序,你应该首先转换为整数。
对于SQL Server 2017 或更高版本那么你已经得到了答案。但是如果 SQL 服务器比 2017 年旧,你可以使用 stuff() 和 XML PATH FOR() 来获得你想要的结果:
由于您使用的是 SQL Server 2017 或更高版本,请不要使用此解决方案,而应使用带有 string_agg() 的解决方案,因为该解决方案更快且易于实施。
架构:
create table MyTable (color varchar(10), [order] int);
insert into MyTable values('Red', 49);
insert into MyTable values('Blue', 32);
insert into MyTable values('Green', 80);
insert into MyTable values('Green', 30);
insert into MyTable values('Blue', 93);
insert into MyTable values('Blue', 77);
insert into MyTable values('Red', 20);
insert into MyTable values('Green', 54);
insert into MyTable values('Red', 59);
insert into MyTable values('Red', 42);
insert into MyTable values('Red', 81);
insert into MyTable values('Green', 35);
insert into MyTable values('Blue', 91);
查询:
SELECT color,count(*) [Count],
STUFF((SELECT ',' + COALESCE(LTRIM(RTRIM([order])), '')
FROM MyTable mt
WHERE mt.color = m.color
order by [order]
FOR XML PATH('') ), 1, 1, ''
) as AggOrder
FROM MyTable m
group by color
输出:
color | Count | AggOrder |
---|---|---|
Blue | 4 | 32,77,91,93 |
Green | 4 | 30,35,54,80 |
Red | 5 | 20,42,49,59,81 |
db<>fiddle here