Explicar
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[0]
retorna o mesmo que
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[17]
que é NULO. Cito os documentos sobre o assunto:
Por padrão, o valor do índice do limite inferior das dimensões de uma matriz é definido como um.
0
não tem nenhum significado especial aqui. Além disso, com arrays bidimensionais, você precisa de dois índices para obter um elemento base. Assim:SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[1][2]
Resultado:
2
A primeira parte da sua mensagem é um pouco obscura.
SELECT array_dims(ARRAY[[1,2,3], [4,5,6], [7,8,9]])
Resultado:
[1:3][1:3]
São dois dimensões com 3 elementos (1 a 3) cada (9 elementos base).
Se você quiser
n-1
dimensões, então este é um resultado correto:SELECT ARRAY (SELECT unnest('{{1,2,3}, {4,5,6}, {7,8,9}}'::int[]))
Resultado:
{1,2,3,4,5,6,7,8,9}
Isso é um dimensão.
unnest()
sempre produz um elemento base por linha. Não tenho certeza de qual resultado você deseja exatamente. Seu exemplo é apenas outra matriz bidimensional com um conjunto ausente de colchetes ... ? {1,2,3}, {4,5,6}, {7,8,9}
Se você quiser uma fatia da matriz , tente esta notação:
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[1:2]
Resultado:
{{1,2,3},{4,5,6}}
Ou isto:
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[2:2][1:2]
Resultado:
{{4,5}}
Para achatar o resultado (obtenha uma matriz 1D):
- Como selecionar uma matriz 1d de uma matriz 2d postgresql
Leia mais no manual aqui.
Função
Testes posteriores revelaram que esta função plpgsql é muito mais rápido. Requer Postgres 9.1 ou posterior:
CREATE OR REPLACE FUNCTION unnest_2d_1d(ANYARRAY, OUT a ANYARRAY)
RETURNS SETOF ANYARRAY AS
$func$
BEGIN
FOREACH a SLICE 1 IN ARRAY $1 LOOP
RETURN NEXT;
END LOOP;
END
$func$ LANGUAGE plpgsql IMMUTABLE;
Ver:
- Como desaninhar um array 2d em um array 1d rapidamente no PostgreSQL?
Esta é uma versão melhorada e simplificada da função que Lukas postou:
CREATE OR REPLACE FUNCTION unnest_2d_1d(anyarray)
RETURNS SETOF anyarray 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$ LANGUAGE sql IMMUTABLE;
Para versões do Postgres <8.4,
array_agg()
não é instalado por padrão. Crie primeiro:CREATE AGGREGATE array_agg(anyelement) (
SFUNC=array_append,
STYPE=anyarray,
INITCOND='{}'
);
Além disso,
generate_subscripts()
ainda não nasceu. Use em vez disso:...
FROM generate_series(array_lower($1,1), array_upper($1,1)) d1
, generate_series(array_lower($1,2), array_upper($1,2)) d2
...
Ligar:
SELECT unnest_2d_1d(ARRAY[[1,2], [3,4], [5,6]]);
Resultado
{1,2}
{3,4}
{5,6}
SQL Fiddle.