Žádné uložené procedury, dočasné tabulky, pouze jeden dotaz a efektivní plán provádění s indexem ve sloupci data:
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);
Mělo by být docela zřejmé, co se zde děje, kromě tohoto zaříkávání:
floor(dateDiff('2012-12-31', dateStampColumn) / 30)
Tento výraz se objeví několikrát a vyhodnotí se jako počet období před 30 dny dateStampColumn
je. dateDiff
vrátí rozdíl ve dnech, vydělíte jej 30, abyste jej dostali za 30denní období, a vše zařadí do floor()
zaokrouhlit na celé číslo. Jakmile máme toto číslo, můžeme GROUP BY
a dále trochu počítáme, abychom toto číslo převedli zpět na počáteční a koncové datum období.
Nahraďte '2012-12-31'
pomocí now()
Pokud preferujete. Zde je několik ukázkových dat:
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');
A výsledek:
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
koncové body období jsou včetně.
Hrajte s tím v SQL Fiddle .
Je tu trochu potenciální praštěnost v tom, že do výsledku nebude zahrnuto jakékoli 30denní období s nulovým počtem odpovídajících řádků. Pokud byste se k tomu mohli připojit podle tabulky období, mohlo by to být odstraněno. MySQL však nemá nic jako generate_series() od PostgreSQL a> , takže se s tím budete muset vypořádat ve své aplikaci nebo zkusit tento chytrý hack .