Saya melewatkan tag mysql dan menulis solusi ini. Sayangnya, ini tidak berfungsi di MySQL karena tidak mendukung fungsi jendela .
Saya tetap mempostingnya, karena saya berusaha keras. Diuji dengan PostgreSQL. Akan bekerja sama dengan Oracle atau SQL Server (atau RDBMS layak lainnya yang mendukung fungsi jendela).
Pengaturan pengujian
CREATE TEMP TABLE v(id int, visit date);
INSERT INTO v VALUES
(444631, '2011-11-07')
,(444631, '2011-11-06')
,(444631, '2011-11-05')
,(444631, '2011-11-04')
,(444631, '2011-11-02')
,(444631, '2011-11-01')
,(444632, '2011-12-02')
,(444632, '2011-12-03')
,(444632, '2011-12-05');
Versi sederhana
-- add 1 to "difference" to get number of days of the longest period
SELECT id, max(dur) + 1 as max_consecutive_days
FROM (
-- calculate date difference of min and max in the group
SELECT id, grp, max(visit) - min(visit) as dur
FROM (
-- consecutive days end up in a group
SELECT *, sum(step) OVER (ORDER BY id, rn) AS grp
FROM (
-- step up at the start of a new group of days
SELECT id
,row_number() OVER w AS rn
,visit
,CASE WHEN COALESCE(visit - lag(visit) OVER w, 1) = 1
THEN 0 ELSE 1 END AS step
FROM v
WINDOW w AS (PARTITION BY id ORDER BY visit)
ORDER BY 1,2
) x
) y
GROUP BY 1,2
) z
GROUP BY 1
ORDER BY 1
LIMIT 1;
Keluaran:
id | max_consecutive_days
--------+----------------------
444631 | 4
Lebih cepat / lebih pendek
Saya kemudian menemukan cara yang lebih baik. grp
jumlahnya tidak terus menerus (tetapi terus meningkat). Tidak masalah, karena itu hanya sarana untuk mencapai tujuan:
SELECT id, max(dur) + 1 AS max_consecutive_days
FROM (
SELECT id, grp, max(visit) - min(visit) AS dur
FROM (
-- subtract an integer representing the number of day from the row_number()
-- creates a "group number" (grp) for consecutive days
SELECT id
,EXTRACT(epoch from visit)::int / 86400
- row_number() OVER (PARTITION BY id ORDER BY visit) AS grp
,visit
FROM v
ORDER BY 1,2
) x
GROUP BY 1,2
) y
GROUP BY 1
ORDER BY 1
LIMIT 1;
Lainnya
- A solusi prosedural
untuk masalah serupa.
Anda mungkin dapat menerapkan sesuatu yang serupa di MySQL . - Jawaban yang terkait erat di dba.SE dengan penjelasan ekstensif di sini dan di sini .
- Dan di SO:
GROUP BY dan agregat nilai numerik berurutan