sql >> Databasteknik >  >> RDS >> PostgreSQL

Unnest array med en nivå

Förklara

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

returnerar samma som

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

som är NULL. Jag citerar dokumenten i den frågan:

Som standard är det nedre gränsvärdet för en arrays dimensioner satt till ett.

0 har ingen speciell betydelse här. Med en tvådimensionell array behöver du också två index för att få ett baselement. Så här:

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

Resultat:

2

Den första delen av ditt meddelande är lite otydlig.

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

Resultat:

[1:3][1:3]

Det är två dimensioner med 3 element (1 till 3) vardera (9 baselement).
Om du vill ha n-1 dimensioner så är detta ett korrekt resultat:

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

Resultat:

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

Det är ett dimensionera. unnest() producerar alltid ett baselement per rad. Jag är inte säker på vilket resultat du önskar exakt. Ditt exempel är bara ytterligare en 2-dimensionell array med en saknad uppsättning krulliga parenteser ... ?

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

Om du vill ha en del av arrayen , prova den här notationen:

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

Resultat:

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

Eller det här:

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

Resultat:

{{4,5}}

Att platta ut resultatet (få en 1D-array):

  • Hur man väljer 1d array från 2d array postgresql

Läs mer i manualen här.

Funktion

Senare test visade att denna plpgsql-funktion är mycket snabbare. Kräver Postgres 9.1 eller senare:

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;

Se:

  • Hur man unnestrar en 2d-array till en 1d-array snabbt i PostgreSQL?

Detta är en förbättrad och förenklad version av funktionen Lukas postade:

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-versioner <8.4, array_agg() är inte installerat som standard. Skapa det först:

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

Även generate_subscripts() är inte född ännu. Använd istället:

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

Ring:

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

Resultat

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

SQL-fiol.



  1. Uppdatera data i en MySQL-databas

  2. Azure SQL Database Automatic Tuning

  3. SQL Server Delete Statement:Hur man tar bort en eller multiplicerar rader från tabellen

  4. Postgres släpptabell syntaxfel