Cara mengelompokkan tanggal mulai dan tanggal akhir dari beberapa catatan dalam rentang yang sama dengan sql

Saya memiliki pertanyaan yang mengembalikan saya beberapa catatan seperti di bawah ini:

ip; start_date; end_date
0.0.0.0; 09/10/2018 00: 00: 00; 10/10/2018 01:00:00
0.0.0.0; 10/10/2018 00: 00: 00; 11/10/2018 01:00:00
0.0.0.0; 10/10/2018 00: 00: 00; 11/10/2018 02:00:00
0.0.0.0; 10/10/2018 00: 00: 00; 11/10/2018 03:00:00
0.0.0.0; 10/10/2018 00: 00: 00; 11/10/2018 05:00:00
0.0.0.0; 10/12/2018 00: 00: 00; 10/10/2018 04:00:00

Seperti yang Anda lihat, saya memiliki beberapa catatan bahwa jika kita mengelompokkannya berdasarkan tanggal mulai dan berakhir, keduanya akan berada dalam periode yang sama;

cara mengelompokkan dalam query untuk mendapatkan record sebagai berikut:

0.0.0.0; 09/10/2018 00: 00: 00; 11/10/2018 05:00:00
0.0.0.0; 10/12/2018 00: 00: 00; 10/10/2018 04:00:00

Seperti yang Anda lihat, 5 baris pertama berada dalam rentang yang sama dan baris terakhir tidak.


person user3308496    schedule 11.09.2019    source sumber
comment
Rentang terakhir tampaknya memiliki tanggal_akhir sebelum tanggal_mulai   -  person Nick    schedule 12.09.2019
comment
RDBMS mana yang Anda gunakan?   -  person GMB    schedule 12.09.2019
comment
Selain pengamatan Nick... Anda ingin dua interval berada dalam grup yang sama dalam kondisi apa? Bahwa ada jalur interval yang tumpang tindih di antara keduanya? Yah, ini akan berbau seperti pernyataan-dengan-rekursif atau seperti itu, saya kira   -  person Islingre    schedule 12.09.2019


Jawaban (1)


Anda dapat menggunakan max() kumulatif untuk melihat di mana terdapat tumpang tindih. Jika tidak ada tumpang tindih, maka kelompok dimulai. Jumlah kumulatif awal menentukan setiap "pulau" dan langkah terakhir adalah agregasi:

select ip, grp,
       min(start_date), max(end_date)
from (select t.*,
             sum(case when prev_max_end_date >= start_date
                      then 0 else 1
                 end) over (partition by ip order by start_date) as grp
      from (select t.*,
                   max(end_date) over (partition by ip 
                                       order by start_date
                                       rows between unbounded preceding and 1 preceding
                                      ) as prev_max_end_date
            from t
           ) t
      ) t
group by ip, grp;
person Gordon Linoff    schedule 12.09.2019