2017-10-02 22 views
1

2対の部分で分割配列が必要です。近くの値のみが必要です。たとえば は、私は次の配列があります。PostgreSQLの部分で配列を分割

select array[1,2,3,4,5] 

をそして私は、次の値を持つ4行を取得したい:

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

私はSQLクエリでそれを行うことができますか?

+0

私は生のSQLでそれを行う方法を想像することはできません - あなたはplpgsqlが精通していますか? –

答えて

2
select a 
from (
    select array[e, lead(e) over()] as a 
    from unnest(array[1,2,3,4,5]) u(e) 
) a 
where not exists (
    select 1 
    from unnest(a) u (e) 
    where e is null 
); 
    a 
------- 
{1,2} 
{2,3} 
{3,4} 
{4,5} 
+0

または[\ a [2 \]はnullではありません。 "(http://dbfiddle.uk/?rdbms=postgres_9.6&fiddle=43db545798b8cf23e6a2d840f460d5ff)のためのあなたのgo-toツールであるはずですか? –

+0

@JackDouglas Good –

+0

また、OPsサンプル配列内での順序付けを想定せず、 'over(order by e)'を使うのが最善でしょう。 –

0

1つのオプションは、再帰的cteでこれを行うことです。配列の最初の位置から始まり、最後の位置に移動します。

with recursive cte(a,val,strt,ed,l) as 
(select a,a[1:2] as val,1 strt,2 ed,cardinality(a) as l 
from t 
union all 
select a,a[strt+1:ed+1],strt+1,ed+1,l 
from cte where ed<l 
) 
select val from cte 

aのcteは配列である。

配列の最大長がわかっている場合は、generate_seriesを使用して、1から最大長までのすべての数値を取得し、カーディナリティで配列テーブルを交差結合することもできます。次に、leadを使用して配列のスライスを取得し、最後のものを省略します(特定のパーティションの最後の行にあるleadnullとなります)。

with nums(n) as (select * from generate_series(1,10)) 
select a,res 
from (select a,t.a[nums.n:lead(nums.n) over(partition by t.a order by nums.n)] as res 
     from nums 
     cross join t 
     where cardinality(t.a)>=nums.n 
    ) tbl 
where res is not null