2017-05-12 4 views
2

Ich bin total verwirrt darüber, was SQL-Array-Indizierung tut und was die Rückgabetypen der Indizierung [] sein sollte.So extrahieren Zeile aus Int [] [] als Int [] in Postgres

Ich habe einen 3,2-Array:

select ARRAY[ 
    [1,1], 
    [2,2], 
    [3,3]]; 

--> {{1,1},{2,2},{3,3}} 

(BTW, pgadmin3 sagt dies ist ein "Array integer []", nicht "Array integer [] []").

Lassen Sie uns sagen, dass ich die erste Zeile extrahieren möchten (Indizes beginnen bei 1 oder?):

-- A 
select (ARRAY[ 
    [1,1], 
    [2,2], 
    [3,3]])[1]; 
--> NULL 

Huh? Warum nicht {1,1} (vom Typ int[]).

-- B 
select (ARRAY[ 
    [1,1], 
    [2,2], 
    [3,3]])[1][:]; 

--> {{1,1}} 

... scheint echt. Aber:

-- C 
select (ARRAY[ 
    [1,1], 
    [2,2], 
    [3,3]])[1][:][1]; 
--> {} 

Warum ist das anders als A?

Und wie kann ich eine Zeile aus einem int [] [] (1d Array) als int [] (1d Array) extrahieren.

Antwort

2

Wie Zeile extrahieren von int [] [] als int [] in Postgres

Durch die Aggregation von nicht verschachtelten Elementen:

select array_agg(elem) 
from unnest(array[[1,1],[2,2],[3,3]]) elem; 

    array_agg 
--------------- 
{1,1,2,2,3,3} 
(1 row) 

Sie können mehr Informationen in diesem Beitrag finden: How to get the dimensionality of an ARRAY column?


Wenn Sie die zweite Sub-Array erhalten möchten:

with my_data(id, arr) as (
values 
(1, array[ 
    [1,1], 
    [2,2], 
    [3,3]]), 
(2, array[ 
    [1,1,11], 
    [2,2,22], 
    [3,3,33]]) 
) 

select array_agg(elem) 
from my_data, 
unnest(arr[2:2]) elem 
group by id; 

array_agg 
----------- 
{2,2} 
{2,2,22} 
(2 rows) 

Anmerkung1. Die Notation [2:2] bedeutet einen Schnitt vom 2. Element zum 2. Element, also zeigt es auf das zweite Subarray.

Hinweis 2. Mehrdimensionale Arrays müssen Array-Ausdrücke mit übereinstimmenden Dimensionen haben.

+0

Diese alle Zeilen bekommen. Was ist, wenn ich die zweite Reihe möchte? – user48956

+0

Siehe die bearbeitete Antwort. – klin

+0

Ein '{{...}}' ist ein 2D-Array. Ich möchte ein 1D-Array (die Zeile). Es macht einen Unterschied, denn arr [1] gibt NULL ist arr ist 2d, oder das Element, wenn es 1d ist. – user48956

1

Zusätzlich zu der Antwort der klin und mit der Funktion versehen here (mit einigen Korrekturen):

-- drop operator if exists -> (anyarray, int); 
-- drop function if exists array_by_index(anyarray, int); 
-- drop function if exists reduce_dim(anyarray); 

create or replace function reduce_dim(anyarray) 
returns setof anyarray as 
$function$ 
declare 
    s $1%type; 
begin 
    if ($1 = '{}') or ($1 is null) then 
    return; 
    else 
    foreach s slice 1 in array $1 loop 
     return next s; 
    end loop; 
    return; 
    end if; 
end; 
$function$ 
language plpgsql immutable; 

create function array_by_index(anyarray, int) returns anyarray 
    language sql 
    immutable 
as $$ 
    select case when count(*) = 1 then reduce_dim($1[$2:$2]) else array_agg(x) end 
    from reduce_dim($1[$2:$2]) x 
$$; 

create operator -> (procedure = array_by_index, leftarg = anyarray, rightarg = int); 

select 
    array[[[1,1],[2,2]],[[3,3],[4,4]]]->2, 
    array[[1,2],[3,4],[5,6]]->3, 
    array[[1,2],[3,4],[5,6]]->3->1; 
╔═══════════════╤══════════╤══════════╗ 
║ ?column? │ ?column? │ ?column? ║ 
╠═══════════════╪══════════╪══════════╣ 
║ {{3,3},{4,4}} │ {5,6} │ {5}  ║ 
╚═══════════════╧══════════╧══════════╝ 
Verwandte Themen