Tidak ada prosedur tersimpan, tabel sementara, hanya satu kueri, dan rencana eksekusi efisien yang diberikan indeks pada kolom tanggal:
select
subdate(
'2012-12-31',
floor(dateDiff('2012-12-31', dateStampColumn) / 30) * 30 + 30 - 1
) as "period starting",
subdate(
'2012-12-31',
floor(dateDiff('2012-12-31', dateStampColumn) / 30) * 30
) as "period ending",
count(*)
from
YOURTABLE
group by floor(dateDiff('2012-12-31', dateStampColumn) / 30);
Seharusnya cukup jelas apa yang terjadi di sini, kecuali mantra ini:
floor(dateDiff('2012-12-31', dateStampColumn) / 30)
Ekspresi itu muncul beberapa kali, dan mengevaluasi jumlah periode 30 hari yang lalu dateStampColumn
adalah. dateDiff
mengembalikan perbedaan dalam hari, membaginya dengan 30 untuk mendapatkannya dalam periode 30 hari, dan memasukkan semuanya ke floor()
untuk membulatkannya menjadi bilangan bulat. Setelah kita memiliki nomor ini, kita dapat GROUP BY
itu, dan selanjutnya kami melakukan sedikit matematika untuk menerjemahkan angka ini kembali ke tanggal awal dan akhir periode.
Ganti '2012-12-31'
dengan now()
jika kamu memilih. Berikut beberapa contoh data:
CREATE TABLE YOURTABLE
(`Id` int, `dateStampColumn` datetime);
INSERT INTO YOURTABLE
(`Id`, `dateStampColumn`)
VALUES
(1, '2012-10-15 02:00:00'),
(1, '2012-10-17 02:00:00'),
(1, '2012-10-30 02:00:00'),
(1, '2012-10-31 02:00:00'),
(1, '2012-11-01 02:00:00'),
(1, '2012-11-02 02:00:00'),
(1, '2012-11-18 02:00:00'),
(1, '2012-11-19 02:00:00'),
(1, '2012-11-21 02:00:00'),
(1, '2012-11-25 02:00:00'),
(1, '2012-11-25 02:00:00'),
(1, '2012-11-26 02:00:00'),
(1, '2012-11-26 02:00:00'),
(1, '2012-11-24 02:00:00'),
(1, '2012-11-23 02:00:00'),
(1, '2012-11-28 02:00:00'),
(1, '2012-11-29 02:00:00'),
(1, '2012-11-30 02:00:00'),
(1, '2012-12-01 02:00:00'),
(1, '2012-12-02 02:00:00'),
(1, '2012-12-15 02:00:00'),
(1, '2012-12-17 02:00:00'),
(1, '2012-12-18 02:00:00'),
(1, '2012-12-19 02:00:00'),
(1, '2012-12-21 02:00:00'),
(1, '2012-12-25 02:00:00'),
(1, '2012-12-25 02:00:00'),
(1, '2012-12-26 02:00:00'),
(1, '2012-12-26 02:00:00'),
(1, '2012-12-24 02:00:00'),
(1, '2012-12-23 02:00:00'),
(1, '2012-12-31 02:00:00'),
(1, '2012-12-30 02:00:00'),
(1, '2012-12-28 02:00:00'),
(1, '2012-12-28 02:00:00'),
(1, '2012-12-30 02:00:00');
Dan hasilnya:
period starting period ending count(*)
2012-12-02 2012-12-31 17
2012-11-02 2012-12-01 14
2012-10-03 2012-11-01 5
titik akhir periode sudah termasuk.
Mainkan ini di SQL Fiddle .
Ada sedikit potensi keanehan karena periode 30 hari dengan nol baris yang cocok tidak akan disertakan dalam hasil. Jika Anda bisa menggabungkan ini dengan tabel periode, itu bisa dihilangkan. Namun, MySQL tidak memiliki apa pun seperti PostgreSQL generate_series() , jadi Anda harus menghadapinya di aplikasi Anda atau coba peretasan pintar ini .