Ответ 1
GROUP BY YEAR(record_date), MONTH(record_date)
Просмотрите функции даты и времени в MySQL.
Возможно ли, что я делаю простой запрос, чтобы подсчитать, сколько записей у меня есть за определенный период времени, например год, месяц или день, с полем TIMESTAMP
, например:
SELECT COUNT(id)
FROM stats
WHERE record_date.YEAR = 2009
GROUP BY record_date.YEAR
Или даже:
SELECT COUNT(id)
FROM stats
GROUP BY record_date.YEAR, record_date.MONTH
Чтобы получить ежемесячную статистику.
Спасибо!
GROUP BY YEAR(record_date), MONTH(record_date)
Просмотрите функции даты и времени в MySQL.
GROUP BY DATE_FORMAT(record_date, '%Y%m')
Примечание (в первую очередь, к потенциальным downvoters). В настоящее время это может быть не так эффективно, как другие предложения. Тем не менее, я оставляю это как альтернативу, а также тот, который может служить тому, как быстрее другие решения. (Ибо вы не можете сказать быстро от медленного до тех пор, пока не увидите разницу.) Кроме того, со временем могут быть внесены изменения в движок MySQL в отношении оптимизации, чтобы сделать это решение на некоторых (возможно, не так) далекой) точки в будущем, чтобы стать вполне сопоставимым по эффективности с большинством других.
Я попытался использовать вышеприведенное выражение "WHERE", я подумал, что это правильно, поскольку никто не исправил его, но я ошибся; после некоторых поисков я выяснил, что это правильная формула для оператора WHERE, поэтому код будет выглядеть следующим образом:
SELECT COUNT(id)
FROM stats
WHERE YEAR(record_date) = 2009
GROUP BY MONTH(record_date)
попробуйте этот
SELECT COUNT(id)
FROM stats
GROUP BY EXTRACT(YEAR_MONTH FROM record_date)
EXTRACT (unit FROM date) лучше, поскольку используется меньшая группировка, и функция возвращает числовое значение.
Условие сравнения при группировке будет быстрее, чем функция DATE_FORMAT (которая возвращает строковое значение). Попробуйте использовать поле function |, возвращающее нестроковое значение для условия сравнения SQL (WHERE, HAVING, ORDER BY, GROUP BY).
Если ваш поиск длится несколько лет, и вы все еще хотите ежемесячно собираться в группу, я предлагаю:
версия # 1:
SELECT SQL_NO_CACHE YEAR(record_date), MONTH(record_date), COUNT(*)
FROM stats
GROUP BY DATE_FORMAT(record_date, '%Y%m')
версия # 2 (более эффективная) :
SELECT SQL_NO_CACHE YEAR(record_date), MONTH(record_date), COUNT(*)
FROM stats
GROUP BY YEAR(record_date)*100 + MONTH(record_date)
Я сравнил эти версии с большой таблицей с 1 357 918 строками (innodb), и вторая версия, по-видимому, имеет лучшие результаты.
версия1 (в среднем 10 выполняются): 1,404 секунды
версия2 (в среднем 10 выполняется): 0.780 секунд
(SQL_NO_CACHE
добавлена для предотвращения MySQL от CACHING к запросам.)
Если вы хотите группировать по дате в MySQL, используйте следующий код:
SELECT COUNT(id)
FROM stats
GROUP BY DAYOFMONTH(record_date)
Надеюсь, это избавит некоторое время от тех, кто собирается найти этот поток.
Если вы хотите отфильтровать записи за определенный год (например, 2000), тогда оптимизируйте предложение WHERE
следующим образом:
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.
Вместо:
WHERE YEAR(date_column) = 2000
-- average 0.132 sec.
Результаты были сгенерированы против таблицы, содержащей строки 300k и индекс в столбце даты.
Что касается предложения GROUP BY
, я проверил три варианта против вышеупомянутой таблицы; вот результаты:
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.
Последний победитель.
Полное и простое решение с аналогичной производительностью, но более короткой и более гибкой альтернативой, действующей в настоящее время:
SELECT COUNT(*) FROM stats
-- GROUP BY YEAR(record_date), MONTH(record_date), DAYOFMONTH(record_date)
GROUP BY DATE_FORMAT(record_date, '%Y-%m-%d')
Если вы хотите получать ежемесячную статистику с подсчетом строк в месяц каждого года, заказанного по последнему месяцу, попробуйте следующее:
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
Вы можете сделать это просто функцией Mysql DATE_FORMAT() в GROUP BY. Возможно, вы захотите добавить дополнительный столбец для большей ясности в некоторых случаях, например, когда записи охватывают несколько лет, а один и тот же месяц встречается в разные годы. Здесь так много вариантов, которые можно настроить. Пожалуйста, прочитайте это перед началом. Надеюсь, это будет очень полезно для вас. Вот пример запроса для вашего понимания
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 ');
Следующий запрос работал у меня в 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);
Я предпочитаю оптимизировать выбор группы за один год следующим образом:
SELECT COUNT(*)
FROM stats
WHERE record_date >= :year
AND record_date < :year + INTERVAL 1 YEAR;
Таким образом вы можете просто привязать год один раз, например. '2009'
с именованным параметром и не нужно беспокоиться о добавлении '-01-01'
или передаче в '2010'
отдельно.
Кроме того, поскольку предположим, что мы просто подсчитываем строки и id
никогда не NULL
, я предпочитаю COUNT(*)
- COUNT(id)
.
.... 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')
--- > MAY
.... group by to_char(date,'YY')
--- > 89
попробуй это будет работать!
SELECT COUNT(id)
FROM stats
GROUP BY EXTRACT(YEAR_MONTH FROM record_date)