Возможно ли, что я сделаю простой запрос, чтобы подсчитать, сколько записей у меня за определенный период времени, например, год, месяц или день, с полем 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
Иметь ежемесячную статистику.
Спасибо!
< код > ГРУП < a href = "http://dev.mysql.com/doc/refman/4.1/en/date-and-time-functions.html#function_date-format" > DATE_FORMAT < ; > ; ; ; (recode_date, '% Y% Y% M') /
Примечание (в первую очередь, потенциальным даунвотерам). В настоящее время это может быть не так эффективно, как другие предложения. Тем не менее, я оставляю это как альтернативу, и такую, которая может помочь увидеть, насколько быстрее другие решения. (Потому что вы не можете быстро отличить от медленного, пока не увидите разницу.Кроме того, со временем в движок MySQL могут быть внесены изменения в отношении оптимизации, чтобы сделать это решение в какой-то (возможно, не такой отдаленный) момент в будущем довольно сопоставимым по эффективности с большинством других.
Я попытался использовать приведенное выше утверждение «ГДЕ», я подумал, что оно правильное, поскольку никто не исправил его, но я ошибся; после некоторых поисков я обнаружил, что это правильная формула для оператора 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 (единица FROM date) лучше, поскольку используется меньшее группирование, и функция возвращает числовое значение.
Условие сравнения при группировании будет быстрее, чем функция DATE_FORMAT (которая возвращает строковое значение). Попробуйте использовать функцию | поле, которое возвращает нестроковое значение для условия сравнения SQL (ГДЕ, 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 строками ([Tag: InnoDB]) и 2-я версия, кажется, имеет лучшие результаты.
версия1 (в среднем 10 исполнений) : 1,404 секунды < br / > версия2 (в среднем 10 исполнений) : 0,780 секунды < br / >
(Ключ SQL_NO_CACHE
добавлен, чтобы предотвратить MySQL от CACHING к запросам.)
Если вы хотите фильтровать записи за определенный год (например,. 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.
Результаты были получены по таблице, содержащей 300 тыс. Строков и индекс в столбце даты.
Что касается пункта «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')
Вы можете сделать это просто 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 ');
Если вы хотите получать ежемесячную статистику с количеством строк в месяц каждого года, упорядоченного по последнему месяцу, попробуйте это:
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
Следующий запрос работал для меня в 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)
.
.... группа по to_char (дата, 'YYY')
- > 1989
.... группа по to_char (дата, 'MM')
- > 05
.... группа по to_char (дата, 'DD')
--- > 23
.... group by to_char (date, 'MON')
--- > MAY
.... группа по to_char (дата, 'YY')
--- > 89