问题:在 STRING_AGG 函数中使用 distinct 和 order by

我正在尝试使用 string_agg 列,同时对列进行排序,并且只显示唯一值。考虑以下演示。是否存在语法问题,或者我使用的方法根本不可能?

SELECT STRING_AGG(DISTINCT foo.a::TEXT,',' ORDER BY foo.a DESC)
              FROM (
                       SELECT 1 As a
                       UNION ALL
                       SELECT 1
                       UNION ALL
                       SELECT 1
                       UNION ALL
                       SELECT 2
                   ) AS foo

[2019-11-22 13:29:32] [42P10] 错误:在具有 DISTINCT 的聚合中,ORDER BY 表达式必须出现在参数列表 [2019-11-22 13:29:32]职位:53

解答

错误信息非常清楚。您在ORDER BY子句中使用的表达式也必须出现在聚合部分中。

你可以这样做:

SELECT STRING_AGG(DISTINCT foo.a::TEXT, ',' ORDER BY foo.a::TEXT DESC)
FROM (
    SELECT 1 As a
    UNION ALL SELECT 1
    UNION ALL SELECT 1
    UNION ALL SELECT 2
) AS foo

Demo on DB Fiddle

虽然这可行,但此解决方案的问题在于它将数字作为字符串排序,它们没有相同的排序规则。字符串明智,10小于2

另一种选择是使用数组:首先,ARRAY_AGG()可用于聚合数字(具有正确的数字顺序),然后您可以使用ARRAY_TO_STRING()将其转换为以逗号分隔的字符串列表。

SELECT ARRAY_TO_STRING(ARRAY_AGG(DISTINCT a ORDER BY a DESC), ',')
FROM (
    SELECT 1 As a
    UNION ALL SELECT 1
    UNION ALL SELECT 1
    UNION ALL SELECT 2
) AS foo

DB Fiddle 上的演示

Logo

PostgreSQL社区为您提供最前沿的新闻资讯和知识内容

更多推荐