sql >> Databáze >  >> RDS >> PostgreSQL

GROUP BY a agregovat sekvenční číselné hodnoty

Identifikace hodnot, které nejdou po sobě, je vždy trochu složitější a zahrnuje několik vnořených dílčích dotazů (alespoň nemohu přijít na lepší řešení).

Prvním krokem je identifikace hodnot pro rok, které nejdou po sobě:

Krok 1) Identifikujte hodnoty, které nejdou po sobě

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

To vrátí následující výsledek:

 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

Nyní s hodnotou group_cnt můžeme vytvořit „ID skupiny“ pro každou skupinu, která má po sobě jdoucí roky:

Krok 2) Definujte ID skupiny

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

To vrátí následující výsledek:

 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)

Jak můžete vidět, každá "skupina" má své vlastní group_nr a toto můžeme nakonec použít k agregaci přidáním další odvozené tabulky:

Krok 3) Závěrečný dotaz

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

To vrátí následující výsledek:

 company | profession |      years
---------+------------+------------------
 Google  | Programmer | {2000}
 Google  | Sales      | {2000,2001,2002}
 Google  | Sales      | {2004}
 Mozilla | Sales      | {2002}
(4 rows)

Což je přesně to, co jsi chtěl, pokud se nepletu.



  1. Převést „datetime2“ na „datetime“ v SQL Server (příklady T-SQL)

  2. spojit datový sloupec oddělený čárkou

  3. Aktualizace Postgresql s připojením

  4. Jak změnit symbol měny relace v Oracle