Explicar
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[0]
devuelve lo mismo que
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[17]
que es NULO. Cito los documentos sobre ese asunto:
De forma predeterminada, el valor del índice de límite inferior de las dimensiones de una matriz se establece en uno.
0
no tiene un significado especial aquí. Además, con matrices bidimensionales, necesita dos índices para obtener un elemento base. Así:
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[1][2]
Resultado:
2
La primera parte de su mensaje es un poco confusa.
SELECT array_dims(ARRAY[[1,2,3], [4,5,6], [7,8,9]])
Resultado:
[1:3][1:3]
Son dos dimensiones con 3 elementos (1 a 3) cada uno (9 elementos base).
Si quieres n-1
dimensiones entonces este es un resultado correcto:
SELECT ARRAY (SELECT unnest('{{1,2,3}, {4,5,6}, {7,8,9}}'::int[]))
Resultado:
{1,2,3,4,5,6,7,8,9}
Ese es uno dimensión. unnest()
siempre produce un elemento base por fila. No estoy seguro de qué resultado desea exactamente. Su ejemplo es solo otra matriz bidimensional con un conjunto faltante de corchetes... ?
{1,2,3}, {4,5,6}, {7,8,9}
Si desea una parte de la matriz , prueba esta notación:
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[1:2]
Resultado:
{{1,2,3},{4,5,6}}
O esto:
SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[2:2][1:2]
Resultado:
{{4,5}}
Para aplanar el resultado (obtener una matriz 1D):
- Cómo seleccionar una matriz 1d de una matriz 2d postgresql
Lea más en el manual aquí.
Función
Una prueba posterior reveló que esta función plpgsql es mucho más rápido. Requiere Postgres 9.1 o 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:
- ¿Cómo anular una matriz 2d en una matriz 1d rápidamente en PostgreSQL?
Esta es una versión mejorada y simplificada de la función que Lukas publicó:
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 las versiones de Postgres <8.4, array_agg()
no está instalado por defecto. Créalo primero:
CREATE AGGREGATE array_agg(anyelement) (
SFUNC=array_append,
STYPE=anyarray,
INITCOND='{}'
);
Además, generate_subscripts()
no ha nacido, todavía. Utilice en su lugar:
...
FROM generate_series(array_lower($1,1), array_upper($1,1)) d1
, generate_series(array_lower($1,2), array_upper($1,2)) d2
...
Llamar:
SELECT unnest_2d_1d(ARRAY[[1,2], [3,4], [5,6]]);
Resultado
{1,2}
{3,4}
{5,6}
Violín SQL.