Das Identifizieren nicht aufeinanderfolgender Werte ist immer etwas knifflig und beinhaltet mehrere verschachtelte Unterabfragen (zumindest fällt mir keine bessere Lösung ein).
Der erste Schritt besteht darin, nicht aufeinanderfolgende Werte für das Jahr zu identifizieren:
Schritt 1) Identifizieren Sie nicht aufeinanderfolgende Werte
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
Dies gibt das folgende Ergebnis zurück:
company | profession | year | group_cnt ---------+------------+------+----------- Google | Programmer | 2000 | 1 Google | Sales | 2000 | 1 Google | Sales | 2001 | 0 Google | Sales | 2002 | 0 Google | Sales | 2004 | 1 Mozilla | Sales | 2002 | 1
Jetzt können wir mit dem Wert group_cnt "Gruppen-IDs" für jede Gruppe erstellen, die aufeinanderfolgende Jahre hat:
Schritt 2) Gruppen-IDs definieren
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
Dies gibt das folgende Ergebnis zurück:
company | profession | year | group_nr ---------+------------+------+---------- Google | Programmer | 2000 | 1 Google | Sales | 2000 | 2 Google | Sales | 2001 | 2 Google | Sales | 2002 | 2 Google | Sales | 2004 | 3 Mozilla | Sales | 2002 | 4 (6 rows)
Wie Sie sehen können, hat jede „Gruppe“ ihre eigene Gruppennummer und diese können wir schließlich verwenden, um sie zu aggregieren, indem wir eine weitere abgeleitete Tabelle hinzufügen:
Schritt 3) Letzte Abfrage
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
Dies gibt das folgende Ergebnis zurück:
company | profession | years ---------+------------+------------------ Google | Programmer | {2000} Google | Sales | {2000,2001,2002} Google | Sales | {2004} Mozilla | Sales | {2002} (4 rows)
Das ist genau das, was du wolltest, wenn ich mich nicht irre.