sql >> Databáze >  >> RDS >> Mysql

Spočítejte počet řádků v 30denních přihrádkách

Žá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 .



  1. Jaký je ekvivalent PDO funkce mysql_real_escape_string?

  2. Operátor ampersand (&) v klauzuli WHERE serveru SQL Server

  3. Používání Amazon RDS s aplikací pro Android

  4. Nelze se připojit k mysql pod v Kubernetes při použití tajných klíčů pro heslo (přístup odepřen)