PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Annulla l'annidamento dell'array di un livello

Spiega

SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[0]

restituisce lo stesso di

SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[17]

che è NULLA. Cito i documenti sull'argomento:

Per impostazione predefinita, il valore dell'indice di limite inferiore delle dimensioni di una matrice è impostato su uno.

0 non ha alcun significato speciale qui. Inoltre, con un array bidimensionale, hai bisogno di due indici per ottenere un elemento base. In questo modo:

SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[1][2]

Risultato:

2

La prima parte del tuo messaggio non è chiara.

SELECT array_dims(ARRAY[[1,2,3], [4,5,6], [7,8,9]])

Risultato:

[1:3][1:3]

Sono due dimensioni con 3 elementi (da 1 a 3) ciascuno (9 elementi base).
Se vuoi n-1 dimensioni allora questo è un risultato corretto:

SELECT ARRAY (SELECT unnest('{{1,2,3}, {4,5,6}, {7,8,9}}'::int[]))

Risultato:

{1,2,3,4,5,6,7,8,9}

Questo è uno dimensione. unnest() produce sempre un elemento di base per riga. Non sono sicuro di quale risultato desideri esattamente. Il tuo esempio è solo un altro array bidimensionale con una serie mancante di parentesi graffe ... ?

{1,2,3}, {4,5,6}, {7,8,9}

Se vuoi una fetta dell'array , prova questa notazione:

SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[1:2]

Risultato:

{{1,2,3},{4,5,6}}

O questo:

SELECT (ARRAY[[1,2,3], [4,5,6], [7,8,9]])[2:2][1:2]

Risultato:

{{4,5}}

Per appiattire il risultato (ottenere un array 1D):

  • Come selezionare un array 1d da un array 2d postgresql

Leggi di più nel manuale qui.

Funzione

Test successivi hanno rivelato che questa funzione plpgsql è molto Più veloce. Richiede Postgres 9.1 o successivo:

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;

Vedi:

  • Come disnidare rapidamente un array 2d in un array 1d in PostgreSQL?

Questa è una versione migliorata e semplificata della funzione pubblicata da Lukas:

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;

Per le versioni di Postgres <8.4, array_agg() non è installato per impostazione predefinita. Crealo prima:

CREATE AGGREGATE array_agg(anyelement) (
 SFUNC=array_append,
 STYPE=anyarray,
 INITCOND='{}'
);

Inoltre, generate_subscripts() non è ancora nato. Usa invece:

...
FROM   generate_series(array_lower($1,1), array_upper($1,1)) d1
    ,  generate_series(array_lower($1,2), array_upper($1,2)) d2
...

Chiama:

SELECT unnest_2d_1d(ARRAY[[1,2], [3,4], [5,6]]);

Risultato

{1,2}
{3,4}
{5,6}

SQL Fiddle.