tbz*_*tbz 6 sql arrays postgresql group-by postgresql-9.1
我们有一个问题将数组分组到一个数组中.我们希望将两个列中的值连接到一个单独的数组中,并聚合这些多行的数组.
鉴于以下输入:
| id | name | col_1 | col_2 |
| 1 | a | 1 | 2 |
| 2 | a | 3 | 4 |
| 4 | b | 7 | 8 |
| 3 | b | 5 | 6 |
Run Code Online (Sandbox Code Playgroud)
我们想要以下输出:
| a | { 1, 2, 3, 4 } |
| b | { 5, 6, 7, 8 } |
Run Code Online (Sandbox Code Playgroud)
元素的顺序很重要,应该与聚合行的id相关联.
我们尝试了array_agg函数:
SELECT array_agg(ARRAY[col_1, col_2]) FROM mytable GROUP BY name;
Run Code Online (Sandbox Code Playgroud)
不幸的是,这句话引发了一个错误:
ERROR: could not find array type for data type character varying[]
Run Code Online (Sandbox Code Playgroud)
似乎不可能使用array_agg在group by子句中合并数组.
有任何想法吗?
UNION ALL你可以先用"反转" UNION ALL:
SELECT name, array_agg(c) AS c_arr
FROM (
SELECT name, id, 1 AS rnk, col1 AS c FROM tbl
UNION ALL
SELECT name, id, 2, col2 FROM tbl
ORDER BY name, id, rnk
) sub
GROUP BY 1;
Run Code Online (Sandbox Code Playgroud)
适合生成您稍后请求的值的顺序.每个文件:
集合函数
array_agg,json_agg,string_agg,和xmlagg,以及类似用户定义集合函数,产生依赖于输入值的顺序上有意义不同的结果值.默认情况下,此排序未指定,但可以通过ORDER BY在聚合调用中编写子句来控制,如第4.2.7节所示.或者,从排序的子查询中提供输入值通常会起作用.
或者你可以创建一个自定义聚合函数,就像在这些相关答案中讨论的那样:
在Postgres数组中选择数据在PostgreSQL中
是否有类似两个数组的zip()函数?
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
,STYPE = anyarray
,INITCOND = '{}'
);
Run Code Online (Sandbox Code Playgroud)
然后你可以:
SELECT name, array_agg_mult(ARRAY[col1, col2] ORDER BY id) AS c_arr
FROM tbl
GROUP BY 1
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)
或者,通常更快,而不是SQL标准:
SELECT name, array_agg_mult(ARRAY[col1, col2]) AS c_arr
FROM (SELECT * FROM tbl ORDER BY name, id) t
GROUP BY 1;
Run Code Online (Sandbox Code Playgroud)
添加的ORDER BY id(可以附加到这样的聚合函数)保证您期望的结果:
{1,2,3,4}
{5,6,7,8}
Run Code Online (Sandbox Code Playgroud)
或者您可能对此替代方案感兴趣:
SELECT name, array_agg_mult(ARRAY[ARRAY[col1, col2]] ORDER BY id) AS c_arr
FROM tbl
GROUP BY 1
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)
哪个产生二维数组:
{{1,2},{3,4}}
{{5,6},{7,8}}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3668 次 |
| 最近记录: |