PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

GROUP BY dan agregat nilai numerik berurutan

Mengidentifikasi nilai yang tidak berurutan selalu sedikit rumit dan melibatkan beberapa sub-kueri bersarang (setidaknya saya tidak dapat menemukan solusi yang lebih baik).

Langkah pertama adalah mengidentifikasi nilai yang tidak berurutan untuk tahun tersebut:

Langkah 1) Identifikasi nilai yang tidak berurutan

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

Ini mengembalikan hasil berikut:

 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

Sekarang dengan nilai group_cnt kita dapat membuat "ID grup" untuk setiap grup yang memiliki tahun berturut-turut:

Langkah 2) Tentukan ID grup

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

Ini mengembalikan hasil berikut:

 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)

Seperti yang Anda lihat, setiap "grup" memiliki group_nr-nya sendiri dan ini akhirnya dapat kita gunakan untuk mengagregasi dengan menambahkan tabel turunan lainnya:

Langkah 3) Kueri terakhir

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

Ini mengembalikan hasil berikut:

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

Yang persis seperti yang Anda inginkan, jika saya tidak salah.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Menemukan Interval Antara Dua Tanggal di PostgreSQL

  2. apa itu @JoinColumn dan bagaimana menggunakannya di Hibernate

  3. tidak ada entri FROM-klausa untuk tabel Grupo cakephp

  4. Kurangi Tahun dari Tanggal di PostgreSQL

  5. Bagaimana cara membuat kueri case-insensitive di Postgresql?