如何选择整数数组的每个第一个元素到数组?
{{1,2,3},{2,15,32},{5,16,14},...}
- > {1,2,5,...}
答案 0 :(得分:2)
由于PostgreSQL允许在数组大小之外寻求切片,并假设永远不会有超过999个子数组,我们可以使用这个怪物
WITH data AS (
SELECT array[array[1,2,3], array[2,15,32], array[5,16,14]] as arr)
SELECT array_agg(arr)
FROM (SELECT unnest(arr[1:999][1]) as arr from data) data2;
如果需要,你当然可以增加常数999,它只是我投入的一个随机大数字。
之所以如此复杂,是因为如果你只使用arr[1:999][1]
,你仍会得到一个二维数组,但只有第一个元素。在这种情况下{{1}, {2}, {5}}
。如果我们使用unnest()
,我们可以将其设置为一个集合,然后可以通过subselect将其输入array_agg()
。
使用array_agg(unnest(arr[1:999][1]))
会很好,但聚合功能并不喜欢套装,我也不知道是否有办法即时转换它。
您也可以使用实际的数组长度,但这可能会导致不必要的计算
SELECT unnest(arr[1:array_length(arr, 1)][1]) as arr from data
注意强>
如果阵列可以被一个级别取消,你可以只索引数组,然后使用array_agg()
将它转换回一个语法更简单的数组
WITH data AS
(SELECT array[1,2,3] as arr
UNION ALL SELECT array[2,15,32] as arr
UNION ALL SELECT array[5,16,14] as arr)
SELECT array_agg(arr[1]) from data;
CTE仅用于输入数据,实际的肉是array_agg(arr[1])
。这当然适用于任意数量的输入数组。
答案 1 :(得分:1)
鉴于此表:
CREATE TEMP TABLE arrtbl (
arrtbl_id serial PRIMARY KEY
, arr int[]
);
示例值:
INSERT INTO arrtbl (arr)
VALUES
('{{1,2,3},{2,15,32},{5,16,14}}')
, ('{{17,22},{1,15},{16,14}}') -- dimensions can vary across rows!
, ('{}')
, (null);
这将完成所有行的工作:
SELECT arrtbl_id, array_agg(a) AS a1
FROM arrtbl t
, unnest(t.arr[-2147483648:2147483647][1]) a
GROUP BY 1;
为什么[-2147483648:2147483647]
?
结果:
arrtbl_id | a1
----------+-----------
1 | '{1,2,5}'
2 | '{17,1,16}'
请注意,arr
中包含空/ NULL数组的行将从结果中删除
此外,虽然上述通常有效,但请使用此安全语法:
SELECT arrtbl_id, array_agg(a.a ORDER BY a.ordinality)
FROM arrtbl t
LEFT JOIN LATERAL unnest(t.arr[-2147483648:2147483647][1]) WITH ORDINALITY a ON true
GROUP BY 1;
结果:
arrtbl_id | a1
----------+-----------
1 | '{1,2,5}'
2 | '{17,1,16}'
3 | null
4 | null
详细说明:
答案 2 :(得分:0)
Plpgsql解决方案:
create or replace function first_elements(arr anyarray)
returns int[] language plpgsql
as $$
declare
i int;
res int[];
begin
for i in 1..array_length(arr, 1) loop
res = array_append(res, arr[i][1]);
end loop;
return res;
end $$;
with test as (
select array[array[1,2,3], array[2,15,32], array[5,16,14]] a
union
select array[array[101,0], array[102,0]] a
)
select first_elements(a) from test;
first_elements
----------------
{1,2,5}
{101,102}
(2 rows)