Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Policz liczbę rzędów w 30-dniowych pojemnikach

Brak procedur składowanych, tabel tymczasowych, tylko jedno zapytanie i wydajny plan wykonania z indeksem w kolumnie daty:

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

Powinno być całkiem oczywiste, co się tutaj dzieje, z wyjątkiem tej inkantacji:

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

To wyrażenie pojawia się kilka razy i jest obliczane na podstawie liczby okresów 30-dniowych sprzed dateStampColumn jest. dateDiff zwraca różnicę w dniach, dzieli ją przez 30, aby uzyskać ją w okresach 30-dniowych, i podaje wszystko do floor() zaokrąglić do liczby całkowitej. Gdy już mamy ten numer, możemy GROUP BY to, a następnie wykonujemy trochę matematyki, aby przetłumaczyć tę liczbę z powrotem na datę początkową i końcową okresu.

Zastąp '2012-12-31' z now() Jeśli wolisz. Oto kilka przykładowych danych:

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 wynik:

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

punkty końcowe okresu są włącznie.

Pobaw się tym w SQL Fiddle .

Istnieje trochę potencjalnej głupoty w tym, że dowolny 30-dniowy okres bez pasujących wierszy nie zostanie uwzględniony w wyniku. Gdybyś mógł dołączyć do tego z tabelą okresów, można by to wyeliminować. Jednak MySQL nie ma czegoś takiego jak generate_series() , więc musisz sobie z tym poradzić w swojej aplikacji lub spróbuj ten sprytny hack .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nie można połączyć Ruby on Rails ze zdalną bazą danych mysql

  2. Usuń rekord z konsoli — Ruby on Rails

  3. Jak wykonać jednorazowe ładowanie 4 miliardów rekordów z MySQL do SQL Server

  4. Błąd:Fill:Właściwość SelectCommand.Connection nie została zainicjowana.

  5. Liczenie wszystkich wierszy z określonymi kolumnami i grupowanie według tygodnia