Mysql
 sql >> база данни >  >> RDS >> Mysql

Пребройте броя на редовете в кошчетата за 30 дни

Без съхранени процедури, временни таблици, само една заявка и ефективен план за изпълнение с индекс в колоната за дата:

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

Трябва да е доста очевидно какво се случва тук, с изключение на това заклинание:

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

Този израз се появява няколко пъти и се оценява до броя на периодите отпреди 30 дни dateStampColumn е dateDiff връща разликата в дни, разделете я на 30, за да я получите в периоди от 30 дни, и я подадете на floor() за да го закръглите до цяло число. След като имаме този номер, можем да GROUP BY и освен това правим малко математика, за да преведем това число обратно в началната и крайната дата на периода.

Заменете '2012-12-31' с now() ако предпочиташ. Ето някои примерни данни:

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

И резултатът:

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

крайните точки на периода са включени.

Играйте с това в SQL Fiddle .

Има малко потенциална глупост в това, че всеки 30-дневен период с нулеви съвпадащи редове няма да бъде включен в резултата. Ако можете да присъедините това към таблица с периоди, това може да бъде елиминирано. MySQL обаче няма нищо подобно на generate_series() на PostgreSQL a> , така че ще трябва да се справите с него в приложението си или да опитате този умен хак .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изтрийте дублиращи се записи, без да създавате временна таблица

  2. Ресурсът Mysql временно не е наличен

  3. Как да преброите колко пъти две стойности се появяват в две колони в произволен ред

  4. Как да получите набор от резултати като функция за забавяне на Oracle

  5. Съхранение на Lat Lng стойности в MySQL с помощта на пространствен тип точка