Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Baris tabel konsolidasi MySQL dengan rentang tanggal yang tumpang tindih

Salah satu cara melakukannya adalah dengan menggunakan subquery yang berkorelasi:

SELECT DISTINCT
       (SELECT MIN(opens)
       FROM mytable AS t2
       WHERE t2.opens <= t1.closes AND t2.closes >= t1.opens) AS start,
       (SELECT MAX(closes)
       FROM mytable AS t2
       WHERE t2.opens <= t1.closes AND t2.closes >= t1.opens) AS end       
FROM mytable AS t1
ORDER BY opens

WHERE predikat dari subkueri yang berkorelasi:

t2.opens <= t1.closes AND t2.closes >= t1.opens

mengembalikan semua catatan yang tumpang tindih terkait dengan catatan saat ini. Melakukan agregasi satu catatan ini, kita dapat menemukan tanggal mulai / akhir setiap interval:tanggal mulai interval adalah opens minimum tanggal di antara semua catatan yang tumpang tindih, sedangkan tanggal akhir adalah closes maksimum tanggal.

Demo di sini

EDIT:

Solusi di atas tidak akan bekerja dengan serangkaian interval seperti berikut:

1. |-----------|
2. |----|
3.           |-----|

Catatan no. 2, saat diproses, akan menghasilkan interval awal/akhir yang salah.

Berikut solusi menggunakan variabel:

SELECT MIN(start) AS start, MAX(end) AS end
FROM (
  SELECT @grp := IF(@start = '1900-01-01' OR 
                   (opens <= @end AND closes >= @start), @grp, @grp+1) AS grp,        
         @start := IF(@start = '1900-01-01', opens, 
                      IF(opens <= @end AND closes >= @start, 
                         IF (@start < opens, @start, opens), opens)) AS start,
         @end := IF(@end = '1900-01-01', closes, 
                    IF (opens <= @end AND closes >= @start, 
                      IF (@end > closes, @end, closes), closes)) AS end                 
  FROM mytable
  CROSS JOIN (SELECT @grp := 1, @start := '1900-01-01', @end := '1900-01-01') AS vars
  ORDER BY opens, DATEDIFF(closes, opens) DESC) AS t
GROUP BY grp

Idenya adalah mulai dari opens/closes paling kiri selang. Variabel @start , @end digunakan untuk menyebarkan interval konsolidasi yang berkembang secara bertahap (saat baris tumpang tindih baru sedang diproses) ke bawah rantai interval. Setelah interval yang tidak tumpang tindih ditemukan, [@start - @end] diinisialisasi untuk mencocokkan interval baru ini dan grp bertambah satu.

Demo di sini




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana saya bisa menjalankan banyak kueri dalam satu halaman?

  2. Kesalahan koneksi DB MediaWiki saat mencoba meningkatkan ke 1.22

  3. tambahkan kolom sementara dengan nilai

  4. Pembaruan MySQL dengan subquery dalam mode pembaruan aman

  5. Ekspor CSV dari Mysql