如何在 SQL 中对数组进行 string_agg?
Posted
技术标签:
【中文标题】如何在 SQL 中对数组进行 string_agg?【英文标题】:How to string_agg an array in SQL? 【发布时间】: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) 不存在 提示:否 函数匹配给定的名称和参数类型。你可能需要 添加显式类型转换。
【问题讨论】:
【参考方案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;
我更喜欢将结果保留为数组,但如果您愿意,可以轻松地将结果转换为字符串。
【讨论】:
哇,这真的很有帮助。谢谢:)以上是关于如何在 SQL 中对数组进行 string_agg?的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server STRING_AGG() :在 Linq 中等效
2017 年之前 SQL Server 的 String_agg
2017 年之前 SQL Server 的 String_agg
在 SQL Server 中使用 STRING_AGG 获取唯一值