Việc xác định các giá trị không liên tiếp luôn hơi phức tạp và liên quan đến một số truy vấn con lồng nhau (ít nhất là tôi không thể đưa ra giải pháp tốt hơn).
Bước đầu tiên là xác định các giá trị không liên tiếp trong năm:
Bước 1) Xác định các giá trị không liên tiếp
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
Điều này trả về kết quả sau:
công tycompany | 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
Giờ đây với giá trị group_cnt, chúng tôi có thể tạo "ID nhóm" cho từng nhóm có các năm liên tiếp:
Bước 2) Xác định ID nhóm
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
Điều này trả về kết quả sau:
công tycompany | 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)
Như bạn có thể thấy, mỗi "nhóm" có group_nr của riêng mình và cái này cuối cùng chúng ta có thể sử dụng để tổng hợp lại bằng cách thêm một bảng dẫn xuất khác:
Bước 3) Truy vấn cuối cùng
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
Điều này trả về kết quả sau:
công tycompany | profession | years ---------+------------+------------------ Google | Programmer | {2000} Google | Sales | {2000,2001,2002} Google | Sales | {2004} Mozilla | Sales | {2002} (4 rows)
Đó là chính xác những gì bạn muốn, nếu tôi không nhầm.