Grupa zapytań MySQL według dnia / miesiąca / roku

Czy jest możliwe, że wykonam proste zapytanie, aby policzyć ile rekordów mam w określonym przedziale czasu, takim jak rok, miesiąc lub dzień, mając pole TIMESTAMP, takie jak:

SELECT COUNT(id)
FROM stats
WHERE record_date.YEAR = 2009
GROUP BY record_date.YEAR

Lub nawet:

SELECT COUNT(id)
FROM stats
GROUP BY record_date.YEAR, record_date.MONTH

Mieć miesięczną statystykę.

Dzięki!
Author: Salman A, 2009-02-03

13 answers

GROUP BY YEAR(record_date), MONTH(record_date)

Sprawdź Funkcje daty i czasu w MySQL.

 854
Author: codelogic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-03 20:42:32
GROUP BY DATE_FORMAT(record_date, '%Y%m')

Uwaga (przede wszystkim do potencjalnych downvoterów). Obecnie może to nie być tak skuteczne, jak inne sugestie. Mimo to pozostawiam go jako alternatywę, a także taką, która może posłużyć do sprawdzenia, jak szybsze są inne rozwiązania. (Bo nie można odróżnić szybko od powoli, dopóki nie zobaczysz różnicy.) Również, z biegiem czasu, mogą być wprowadzane zmiany w silniku MySQL w zakresie optymalizacji tak, aby To rozwiązanie, w pewnym (być może, nie tak odległym) punkcie w przyszłości, do stają się dość porównywalne pod względem wydajności z większością innych.

 184
Author: Andriy M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-08 23:10:25

Próbowałem użyć powyższej instrukcji "WHERE", myślałem, że jest poprawna, ponieważ nikt jej nie poprawił, ale się myliłem; po kilku poszukiwaniach dowiedziałem się, że jest to właściwa formuła dla instrukcji WHERE, więc kod staje się taki:

SELECT COUNT(id)  
FROM stats  
WHERE YEAR(record_date) = 2009  
GROUP BY MONTH(record_date)
 38
Author: dimazaid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-28 02:42:12

Spróbuj tego

SELECT COUNT(id)
FROM stats
GROUP BY EXTRACT(YEAR_MONTH FROM record_date)

Funkcja EXTRACT (unit FROM date) jest lepsza, ponieważ używane jest mniejsze grupowanie i funkcja zwraca wartość liczbową.

Warunek porównania, gdy grupowanie będzie szybsze niż funkcja DATE_FORMAT (która zwraca wartość łańcuchową). Spróbuj użyć funkcji / pola, które zwracają wartość non-string dla warunku porównania SQL (WHERE, HAVING, ORDER BY, GROUP BY).

 36
Author: fu-chi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-11 03:44:25

Jeśli twoje poszukiwania trwają kilka lat, a nadal chcesz grupować co miesiąc, proponuję:

Wersja #1:

SELECT SQL_NO_CACHE YEAR(record_date), MONTH(record_date), COUNT(*)
FROM stats
GROUP BY DATE_FORMAT(record_date, '%Y%m')

Wersja # 2 (bardziej efektywna):

SELECT SQL_NO_CACHE YEAR(record_date), MONTH(record_date), COUNT(*)
FROM stats
GROUP BY YEAR(record_date)*100 + MONTH(record_date)

Porównałem te wersje na dużym stole z 1,357,918 wierszy (innodb ), a druga wersja wydaje się mieć lepsze wyniki.

Wersja1 (average of 10 executes) : 1.404 seconds
wersja2 (średnia z 10 ocen) : 0.780 sekund

(SQL_NO_CACHE klucz dodany, aby zapobiec buforowaniu MySQL do zapytań.)

 22
Author: mr.baby123,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-27 12:57:01

Jeśli chcesz pogrupować według daty w MySQL użyj poniższego kodu:

 SELECT COUNT(id)
 FROM stats
 GROUP BY DAYOFMONTH(record_date)

Mam nadzieję, że zaoszczędzi to trochę czasu dla tych, którzy znajdą ten wątek.

 15
Author: Haijerome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-10 05:16:36

Jeśli chcesz filtrować rekordy dla danego roku (np. 2000), zoptymalizuj WHERE klauzulę tak:

SELECT MONTH(date_column), COUNT(*)
FROM date_table
WHERE date_column >= '2000-01-01' AND date_column < '2001-01-01'
GROUP BY MONTH(date_column)
-- average 0.016 sec.

Zamiast:

WHERE YEAR(date_column) = 2000
-- average 0.132 sec.

Wyniki zostały wygenerowane na podstawie tabeli zawierającej 300K wierszy i indeksu w kolumnie daty.

Jeśli chodzi o klauzulę GROUP BY, przetestowałem trzy warianty na podstawie powyższej tabeli; oto wyniki:

SELECT YEAR(date_column), MONTH(date_column), COUNT(*)
FROM date_table
GROUP BY YEAR(date_column), MONTH(date_column)
-- codelogic
-- average 0.250 sec.

SELECT YEAR(date_column), MONTH(date_column), COUNT(*)
FROM date_table
GROUP BY DATE_FORMAT(date_column, '%Y%m')
-- Andriy M
-- average 0.468 sec.

SELECT YEAR(date_column), MONTH(date_column), COUNT(*)
FROM date_table
GROUP BY EXTRACT(YEAR_MONTH FROM date_column)
-- fu-chi
-- average 0.203 sec.
Ostatni wygrywa.
 10
Author: Salman A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-18 11:53:45

Jeśli chcesz otrzymywać miesięczne statystyki z liczeniem wierszy na miesiąc każdego roku uporządkowane według ostatniego miesiąca, spróbuj tego:

SELECT count(id),
      YEAR(record_date),
      MONTH(record_date) 
FROM `table` 
GROUP BY YEAR(record_date),
        MONTH(record_date) 
ORDER BY YEAR(record_date) DESC,
        MONTH(record_date) DESC
 7
Author: user3019799,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-22 00:21:49

Kompletne i proste rozwiązanie z podobnie działającą jeszcze krótszą i bardziej elastyczną alternatywą obecnie aktywną:

SELECT COUNT(*) FROM stats
-- GROUP BY YEAR(record_date), MONTH(record_date), DAYOFMONTH(record_date)
GROUP BY DATE_FORMAT(record_date, '%Y-%m-%d')
 7
Author: Cees Timmerman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-07 13:31:43

Poniższe zapytanie działało dla mnie w Oracle Database 12c Release 12.1.0.1.0

SELECT COUNT(*)
FROM stats
GROUP BY 
extract(MONTH FROM TIMESTAMP),
extract(MONTH FROM TIMESTAMP),
extract(YEAR  FROM TIMESTAMP);
 6
Author: Minisha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-22 06:37:50

Możesz to zrobić po prostu Mysql DATE_FORMAT () funkcja w GROUP BY. Możesz dodać dodatkową kolumnę dla zwiększenia jasności w niektórych przypadkach, na przykład, gdy rekordy obejmują kilka lat, a następnie ten sam miesiąc występuje w różnych latach.Tutaj tak wiele opcji można dostosować to. Proszę przeczytać to przed rozpoczęciem. Mam nadzieję, że to powinno być bardzo pomocne dla Ciebie. Oto przykładowe zapytanie dla twojego zrozumienia

SELECT
    COUNT(id),
    DATE_FORMAT(record_date, '%Y-%m-%d') AS DAY,
    DATE_FORMAT(record_date, '%Y-%m') AS MONTH,
    DATE_FORMAT(record_date, '%Y') AS YEAR,

FROM
    stats
WHERE
    YEAR = 2009
GROUP BY
    DATE_FORMAT(record_date, '%Y-%m-%d ');
 5
Author: Faisal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 14:39:37

Wolę optymalizować dobór grupy na rok w ten sposób:

SELECT COUNT(*)
  FROM stats
 WHERE record_date >= :year 
   AND record_date <  :year + INTERVAL 1 YEAR;

W ten sposób możesz po prostu powiązać rok raz, np. '2009', z nazwanym parametrem i nie musisz się martwić o dodanie '-01-01' lub podanie '2010' osobno.

Ponadto, ponieważ przypuszczalnie tylko liczymy wiersze i id nigdy nie jest NULL, wolę COUNT(*) od COUNT(id).

 2
Author: Arth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-22 18:05:32

.... group by to_char(date, 'YYYY') --> 1989

.... group by to_char(date,'MM') -->05

.... group by to_char(date,'DD') --->23

.... group by to_char(date,'MON') --->maj

.... group by to_char(date,'YY') --->89

 -1
Author: aromita sen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-05 12:52:16