PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Entschachteln Sie das Array um eine Ebene

Erklären

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

gibt dasselbe zurück wie

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

was NULL ist. Ich zitiere die Dokumente zu diesem Thema:

Standardmäßig ist der Indexwert der unteren Grenze der Dimensionen eines Arrays auf eins gesetzt.

0 hat hier keine besondere Bedeutung. Außerdem braucht man bei zweidimensionalen Arrays zwei Indizes um ein Basiselement zu erhalten. So:

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

Ergebnis:

2

Der erste Teil Ihrer Nachricht ist etwas unklar.

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

Ergebnis:

[1:3][1:3]

Das sind zwei Dimensionen mit jeweils 3 Elementen (1 bis 3) (9 Basiselemente).
Wenn Sie n-1 wollen Abmessungen, dann ist dies ein korrektes Ergebnis:

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

Ergebnis:

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

Das ist eins Abmessungen. unnest() erzeugt immer ein Basiselement pro Reihe. Ich bin mir nicht sicher, welches Ergebnis Sie genau wünschen. Ihr Beispiel ist nur ein weiteres zweidimensionales Array mit fehlenden geschweiften Klammern ... ?

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

Wenn Sie einen Slice des Arrays wollen , versuchen Sie es mit dieser Notation:

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

Ergebnis:

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

Oder dies:

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

Ergebnis:

{{4,5}}

Zum Abflachen das Ergebnis (ein 1D-Array erhalten):

  • So wählen Sie ein 1d-Array aus einem 2d-Array postgresql aus

Lesen Sie mehr im Handbuch hier.

Funktion

Spätere Tests ergaben, dass diese plpgsql-Funktion viel ist Schneller. Erfordert Postgres 9.1 oder höher:

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;

Siehe:

  • Wie entschachtelt man in PostgreSQL schnell ein 2D-Array in ein 1D-Array?

Dies ist eine verbesserte und vereinfachte Version der Funktion, die Lukas gepostet hat:

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;

Für Postgres-Versionen <8.4, array_agg() ist standardmäßig nicht installiert. Erstellen Sie es zuerst:

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

Auch generate_subscripts() ist noch nicht geboren. Verwenden Sie stattdessen:

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

Aufruf:

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

Ergebnis

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

SQL-Geige.