我想获取一个 n
维度的数组,并返回包含 n-1
维度数组行的集合。例如,取数组 ARRAY[[1,2,3], [4,5,6], [7,8,9]]
并返回一个集合 {1,2 ,3}, {4,5,6}, {7,8,9}
。使用 unnest 返回集合 1,2,3,4,5,6,7,8,9
。
我尝试从 PostgreSQL 8.4 中获取 unnest 函数,它似乎可以满足我的要求:
CREATE OR REPLACE FUNCTION tstng.unnest2(anyarray)
RETURNS SETOF anyelement
LANGUAGE plpgsql
IMMUTABLE
AS $$
BEGIN
RETURN QUERY SELECT $1[i]
FROM generate_series(array_lower($1,1), array_upper($1,1)) i;
END;
$$;
但是,SELECT tstng.unnest2(ARRAY[[1,2,3], [4,5,6], [7,8,9]]);
返回集合 , ,
(即:3 个空行)。
我还发现 SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[0];
返回null,我认为这是我问题的根源。
最佳答案
函数
从 n 维数组中分解出一维数组 - 代表嵌套维度的叶子。 (n>= 1。)
PL/pgSQL
用FOR
loop遍历数组:
CREATE OR REPLACE FUNCTION unnest_nd_1d(a ANYARRAY, OUT a_1d ANYARRAY)
RETURNS SETOF ANYARRAY
LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE STRICT AS
$func$
BEGIN
FOREACH a_1d SLICE 1 IN ARRAY a LOOP
RETURN NEXT;
END LOOP;
END
$func$;
SLICE 1
指示获取一维数组。 (SLICE 2
将采用二维数组。)
PARALLEL SAFE
仅适用于 Postgres 9.6 或更高版本。
后来的测试表明这个 PL/pgSQL 函数是最快的。
相关:
纯SQL
仅适用于二维数组:
CREATE OR REPLACE FUNCTION unnest_2d_1d(anyarray)
RETURNS SETOF anyarray
LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
$func$
SELECT array_agg($1[d1][d2])
FROM generate_subscripts($1,1) d1
, generate_subscripts($1,2) d2
GROUP BY d1
ORDER BY d1
$func$;
这是 the function Lukas posted 的改进和简化版本.
db<> fiddle here
<子>旧sqlfiddle
说明
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[0]
返回相同的:
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[17]
... 这是 NULL
。 The manual :
By default, the lower bound index value of an array's dimensions is set to one.
0
作为数组下标没有特殊意义。对于具有默认索引的 Postgres 数组,那里什么也没有。
此外,对于二维数组,您需要两个索引 来获取基本元素。喜欢:
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[1][2]
结果:
2
您的消息的第一部分有点不清楚。
SELECT array_dims(ARRAY[[1,2,3], [4,5,6], [7,8,9]]);
结果:
[1:3][1:3]
这是二维维度,每个维度有 3 个元素(1 到 3)(9 个基本元素)。
如果您想要 n-1
维度,那么这是正确的结果:
SELECT ARRAY (SELECT unnest('{{1,2,3}, {4,5,6}, {7,8,9}}'::int[]))
结果:
{1,2,3,4,5,6,7,8,9}
这是一个维度。 unnest()
每行生成一个基本元素(无论数组维度如何)。您的示例只是另一个缺少大括号集的二维数组...?
{1,2,3}, {4,5,6}, {7,8,9}
如果你想要一个数组的切片:
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[1:2]
结果:
{{1,2,3},{4,5,6}}
或者:
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[2:2][1:2]
结果:
{{4,5}}
要展平结果(获取一维数组):
对于非常旧的版本
对于 Postgres 版本 < 8.4,默认情况下不安装 array_agg()
。先创建它:
CREATE AGGREGATE array_agg(anyelement) (
SFUNC = array_append,
STYPE = anyarray,
INITCOND = '{}'
);
此外,generate_subscripts()
还没有出生。改用:
...
FROM generate_series(array_lower($1,1), array_upper($1,1)) d1
, generate_series(array_lower($1,2), array_upper($1,2)) d2
...
调用:
SELECT unnest_2d_1d(ARRAY[[1,2], [3,4], [5,6]]);
结果
{1,2}
{3,4}
{5,6}
关于arrays - 将数组取消一级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8137112/