sql >> Database teknologi >  >> RDS >> Mysql

Tæl antallet af rækker i 30 dages skraldespande

Ingen lagrede procedurer, midlertidige tabeller, kun én forespørgsel og en effektiv eksekveringsplan givet et indeks i datokolonnen:

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);

Det burde være ret indlysende, hvad der sker her, bortset fra denne besværgelse:

floor(dateDiff('2012-12-31', dateStampColumn) / 30)

Det udtryk vises flere gange, og det evalueres til antallet af 30-dages perioder siden dateStampColumn er. dateDiff returnerer forskellen i dage, divider den med 30 for at få den i 30-dages perioder, og feed det hele til floor() at afrunde det til et heltal. Når vi har dette nummer, kan vi GROUP BY det, og yderligere laver vi lidt matematik for at oversætte dette tal tilbage til periodens start- og slutdato.

Erstat '2012-12-31' med now() hvis du foretrækker det. Her er nogle eksempeldata:

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');

Og resultatet:

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

periode slutpunkter er inklusive.

Spil med dette i SQL Fiddle .

Der er en smule potentiel fjols i, at enhver 30-dages periode med nul matchende rækker ikke vil blive inkluderet i resultatet. Hvis du kunne slutte dig til dette mod en tabel med perioder, kunne det blive elimineret. MySQL har dog ikke noget som PostgreSQL's generate_series() , så du bliver nødt til at håndtere det i din ansøgning eller prøv dette smarte hack .



  1. Udfyldning af html-formularer med mysql-data ved hjælp af php coming up null

  2. Sådan tælles antallet af gange, to værdier vises i to kolonner i vilkårlig rækkefølge

  3. Eksekveres FØR INSERT-trigger for hver række i indsæt på dubletnøgleopdateringsforespørgsel

  4. MySQL mellem klausul ikke inkluderende?