web-dev-qa-db-ja.com

postgres array_aggエラー:異なる次元の配列を蓄積できません

Postgresqlの区画テーブルで、zoningおよびzoning_description列がarray_aggからテキストにキャストされています。 new.universitiesテーブルには9行あり、出力に9行を返す必要があります。

このクエリの目的は、これらの大学が配置されているすべてのプロパティを検索し、ゾーニングタイプを1つの一意の列に折りたたみ、ジオメトリをマルチポリゴンに結合/分解することです。

select array_agg(distinct dp.zoning) zoning,array_agg(distinct dp.zoning_description) zoning_description,
    uni.school name_,uni.address,'University' type_,1000 buff,st_union(dp.geom) 
from new.universities uni join new.detroit_parcels_update dp
on st_intersects(st_buffer(uni.geom,-10),dp.geom)
group by name_,uni.address,type_,buff

私はこのエラーを受け取ります

ERROR:  cannot accumulate arrays of different dimensionality
********** Error **********

ERROR: cannot accumulate arrays of different dimensionality
SQL state: 2202E

enter image description here

Array_agg(distinct dp.zoning :: text)ゾーニングなどを行うことができますが、これは配列内のネストされた配列を持つ完全にめちゃくちゃになった列を返します... enter image description here

ここでの答えに基づいて、動作しない私の更新されたクエリです

select array_agg(distinct zoning_u) zoning,array_agg(distinct zoning_description_u) zoning_description,
        uni.school name_,uni.address,'University' type_,1000::int buff,st_union(dp.geom) geom
from new.detroit_parcels_update dp,unnest(zoning) zoning_u,
unnest(zoning_description) zoning_description_u
join new.universities uni
on st_intersects(st_buffer(uni.geom,-10),dp.geom)
group by name_,uni.address,type_,buff order by name_

このエラーを取得

ERROR:  invalid reference to FROM-clause entry for table "dp"
LINE 6: on st_intersects(st_buffer(uni.geom,-10),dp.geom)
                                                 ^
HINT:  There is an entry for table "dp", but it cannot be referenced from this part of the query.

********** Error **********

ERROR: invalid reference to FROM-clause entry for table "dp"
SQL state: 42P01
Hint: There is an entry for table "dp", but it cannot be referenced from this part of the query.
Character: 373

うまくいった私の最後のクエリは

with t as(select dp.zoning,dp.zoning_description,uni.school name_,uni.address,'University' type_,1000::int buff,st_union(dp.geom) geom
    from new.detroit_parcels_update dp
    join new.universities uni
    on st_intersects(st_buffer(uni.geom,-10),dp.geom)
    group by name_,uni.address,type_,buff,dp.zoning,zoning_description order by name_
    )
select name_,address,type_,buff,st_union(geom) geom,array_agg(distinct z) zoning, array_agg(distinct zd) zoning_description
from t,unnest(zoning) z,unnest(zoning_description) zd 
group by name_,address,type_,buff
11
ziggy

データの例:

_create table my_table(name text, numbers text[], letters text[]);
insert into my_table values
    ('first',  '{1, 2}', '{a}'   ),
    ('first',  '{2, 3}', '{a, b}'),
    ('second', '{4}',    '{c, d}'),
    ('second', '{5, 6}', '{c}'   );
_

配列ではなく、配列要素を集約する必要があります。 unnest()を使用:

_select 
    name, 
    array_agg(distinct number) as numbers, 
    array_agg(distinct letter) as letters
from 
    my_table, 
    unnest(numbers) as number, 
    unnest(letters) as letter
group by name;

  name  | numbers | letters 
--------+---------+---------
 first  | {1,2,3} | {a,b}
 second | {4,5,6} | {c,d}
(2 rows)    
_

または、カスタム集計を作成することもできます。配列をマージする関数が必要です(重複を削除した連結):

_create or replace function public.array_merge(arr1 anyarray, arr2 anyarray)
    returns anyarray language sql immutable
as $$
    select array_agg(distinct elem order by elem)
    from (
        select unnest(arr1) elem 
        union
        select unnest(arr2)
    ) s
$$;

create aggregate array_merge_agg(anyarray) (
    sfunc = array_merge,
    stype = anyarray
);

select 
    name, 
    array_merge_agg(numbers) as numbers, 
    array_merge_agg(letters) as letters
from my_table
group by name;
_
12
klin