【问题标题】:How to string_agg an array in SQL?如何在 SQL 中对数组进行 string_agg?
【发布时间】:2019-09-10 15:09:12
【问题描述】:

我想使用字符串聚合函数聚合行,但是一列是一个数组。

我有三列:员工、年份、成绩。 Grade 列是一个数组。示例:

Row (1) : Employee: Tom | Year: 2019 | Grades: 11,33
Row (2) : Employee: Tom | Year: 2018 | Grades: 45,24,54

'Grade' 列是一个数组。它代表他当年参加的不同考试的成绩

select 
Employee, 
string_agg (distinct Year, ','),
string_agg (distinct Grades, ',')
from Employee_grades
group by 1

错误:

function string_agg(bigint[], unknown) 不存在 提示:否 函数匹配给定的名称和参数类型。你可能需要 添加显式类型转换。

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    你应该使用强制转换:

    select Employee,
          string_agg(distinct Year::text, ','),
          string_agg(distinct Grades::text, ',') 
    from Employee_grades 
    group by Employee  -- GROUP BY 1 is a bad practice
    

    【讨论】:

    • 谢谢。还要感谢您提到好的/坏的做法。帮助很大
    【解决方案2】:

    如果您真的不关心删除重复项,您可以使用array_to_string() 转换为字符串:

    select employee, array_agg(distinct year),
           string_agg(array_to_string(grades, ','), ',')
    from (values ('Tom', 2019, array[11, 33]),
                 ('Tom', 2018, array[10, 20, 30])
         ) v(employee, year, grades)
    group by employee;
    

    如果您真的想删除重复项,这有点棘手。取消嵌套和重复数据删除可能是唯一的方法:

    with t as (
          select *
          from (values ('Tom', 2019, array[11, 33]),
                       ('Tom', 2018, array[11, 20, 30])
               ) v(employee, year, grades)
         )
    select t.*,
           (select array_agg(distinct grade)
            from t t2 cross join lateral
                 unnest(grades) grade
            where t2.employee = t.employee
           ) as grades
    from (select employee, array_agg(distinct year) as year
          from t
          group by t.employee
         ) t;
    

    我更喜欢将结果保留为数组,但如果您愿意,可以轻松地将结果转换为字符串。

    【讨论】:

    • 哇,这真的很有帮助。谢谢:)
    猜你喜欢
    • 2014-09-14
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 2018-12-22
    • 2013-04-18
    相关资源
    最近更新 更多