PG

2017-10-19 11 views
1

は、PostgreSQLクエリを仮定その2列INTのそれぞれが配列[] [2]PG

  track0       track1 
{{1,2},{5847,5848},{5845,5846}......} {{1,2},{5847,5848},{10716,10715}........} 

{{13,14},{1,2},{5847,5848},{284,285}........} {{13,14},{1,2},{5847,5848},{1284,1285}................} 

どのように最後を除いて、両方の列に共通の主要配列を除去することができるの出力行1? 最初の行では、{1,2}を2つの列から削除する必要があります。 2行目の{13,14},{1,2}は、2つの列から削除する必要があります。

sqlで実行できますか、plpgsqlを使用する必要がありますか?

私はplpgsqlを管理することができましたが、sqlソリューションが好きです。同じペアの順に間隔を設けずに、あなたのサンプル与える

答えて

0

t=# with d(t0,t1) as (values 
     ('{{1,2},{5847,5848},{5845,5846}}'::int[][2],'{{1,2},{5847,5848},{10716,10715}}'::int[][2]) 
    , ('{{13,14},{1,2},{5847,5848},{284,285}}'::int[][2],'{{13,14},{1,2},{5847,5848},{1284,1285}}'::int[][2]) 
    ) 
    , u as (
     select * 
     from d 
     join unnest(t0) with ordinality t(e0,o0) on true 
     left outer join unnest(t1) with ordinality t1(e1,o1) on o0=o1 
    ) 
    , p as (
    select * 
    , case when (
     not lead(e0=e1) over w 
     or not lead(e0=e1,2) over w 
     or e0!=e1 
    ) AND (o1%2) = 1 
     then ARRAY[e0,lead(e0) over w] end r0 
    , case when (
     not lead(e0=e1) over w 
     or not lead(e0=e1,2) over w 
     or e0!=e1 
    ) AND (o1%2) = 1 
     then ARRAY[e1,lead(e1) over w] end r1 
    from u 
    window w as (partition by t0,t1 order by o0) 
    ) 
    select t0,t1,array_agg(r0),array_agg(r1) 
    from p 
    where r0 is not null or r1 is not null 
    group by t0,t1 
    ; 
        t0     |     t1     |   array_agg   |   array_agg 
---------------------------------------+-----------------------------------------+---------------------------+----------------------------- 
{{13,14},{1,2},{5847,5848},{284,285}} | {{13,14},{1,2},{5847,5848},{1284,1285}} | {{5847,5848},{284,285}} | {{5847,5848},{1284,1285}} 
{{1,2},{5847,5848},{5845,5846}}  | {{1,2},{5847,5848},{10716,10715}}  | {{5847,5848},{5845,5846}} | {{5847,5848},{10716,10715}} 
(2 rows) 

あなたは多次元配列のためのいくつかのトリックを追加した場合、合併症の一部を省略見ることができますherehere