連続していない値を特定することは常に少しトリッキーで、いくつかのネストされたサブクエリが必要です (少なくとも、私はより良い解決策を見つけることができません)。
最初のステップは、年の非連続値を特定することです。
ステップ 1) 連続していない値を特定する
select company,
profession,
year,
case
when row_number() over (partition by company, profession order by year) = 1 or
year - lag(year,1,year) over (partition by company, profession order by year) > 1 then 1
else 0
end as group_cnt
from qualification
これにより、次の結果が返されます。
会社 | 職業 | 年 | group_cnt
------+------------+------+-----------
グーグル| プログラマー | 2000年 | 1
グーグル| 販売 | 2000年 | 1
グーグル| 販売 | 2001年 | 0
グーグル| 販売 | 2002年 | 0
グーグル| 販売 | 2004年 | 1
モジラ | モジラ | 販売 | 2002年 | 1
group_cnt 値を使用して、連続した年を持つ各グループの「グループ ID」を作成できます。
ステップ 2) グループ ID を定義する
select company,
profession,
year,
sum(group_cnt) over (order by company, profession, year) as group_nr
from (
select company,
profession,
year,
case
when row_number() over (partition by company, profession order by year) = 1 or
year - lag(year,1,year) over (partition by company, profession order by year) > 1 then 1
else 0
end as group_cnt
from qualification
) t1
これにより、次の結果が返されます。
会社 | 職業 | 年 | group_nr
------+------------+------+----------
グーグル| プログラマー | 2000年 | 1
グーグル| 販売 | 2000年 | 2
グーグル| 販売 | 2001年 | 2
グーグル| 販売 | 2002年 | 2
グーグル| 販売 | 2004年 | 3
モジラ | モジラ | 販売 | 2002年 | 4
(6列)
ご覧のとおり、各「グループ」には独自の group_nr があり、これを最終的に使用して、さらに別の派生テーブルを追加して集計できます。
ステップ 3) 最終クエリ
select company,
profession,
array_agg(year) as years
from (
select company,
profession,
year,
sum(group_cnt) over (order by company, profession, year) as group_nr
from (
select company,
profession,
year,
case
when row_number() over (partition by company, profession order by year) = 1 or
year - lag(year,1,year) over (partition by company, profession order by year) > 1 then 1
else 0
end as group_cnt
from qualification
) t1
) t2
group by company, profession, group_nr
order by company, profession, group_nr
これにより、次の結果が返されます。
会社 | 職業 | 年
------+------------+------------------
グーグル| プログラマー | {2000}
グーグル| 販売 | {2000,2001,2002}
グーグル| 販売 | {2004}
モジラ | モジラ | 販売 | {2002}
(4行)
私が間違っていなければ、それはまさにあなたが望んでいたものです。