如何使用 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