Сервер таблиц Oracle предлагает встроенную функцию TRUNC(timestamp,'DY')
. Эта функция преобразует любую метку времени в полночь в предыдущее воскресенье. Как лучше всего это сделать в MySQL?
Oracle также предлагает TRUNC(timestamp,'MM')
преобразовать метку времени в полночь первого дня месяца, в котором это происходит. В MySQL это просто:
TIMESTAMP(DATE_FORMAT(timestamp, '%Y-%m-01'))
Но этот DATE_FORMAT
трюк неделями не сработает. Я знаю об этой WEEK(timestamp)
функции, но мне действительно не нужен номер недели в году; этот материал для многолетней работы.
TRUNC(date, 'DY' )
получает недели с воскресным началом.'W'
получает начало понедельника, по крайней мере, в моей системе.Ответы:
Вы можете использовать и
YEAR(timestamp)
иWEEK(timestamp)
, и оба этих выражения в предложенииSELECT
иGROUP BY
.Не слишком элегантно, но функционально ...
И, конечно же, вы можете объединить эти две части даты в одно выражение, то есть что-то вроде
SELECT CONCAT(YEAR(timestamp), '/', WEEK(timestamp)), etc... FROM ... WHERE .. GROUP BY CONCAT(YEAR(timestamp), '/', WEEK(timestamp))
Изменить : как указывает Мартин , вы также можете использовать эту
YEARWEEK(mysqldatefield)
функцию, хотя ее вывод не так удобен для глаз, как более длинная формула выше.Редактировать 2 [3 1/2 года спустя!]:
YEARWEEK(mysqldatefield)
С необязательным вторым аргументом (mode
), установленным либо на 0, либо на 2, вероятно, лучший способ агрегирования по полным неделям (то есть включая недели, которые охватывают период с 1 января), если это что желательно.YEAR() / WEEK()
Подход первоначально предложенный в этом ответе есть эффект расщепления агрегированных данных для такого «ТРАНСЗОНАЛЬНЫЙ» недели в два: один с бывшим годом, один с новым годом.Чистая срезка каждый год за счет наличия до двух неполных недель, по одной на каждом конце, часто желательна в бухгалтерском учете и т. Д., И для этого
YEAR() / WEEK()
подход лучше.источник
YEARWEEK()
приводит к результату,INT(6)
который, как я полагаю, будет быстрее сортировать / присоединяться / группироватьсяПринятый выше ответ не сработал для меня, потому что он упорядочил недели в алфавитном порядке, а не в хронологическом порядке:
Вот мое решение для подсчета и группировки по неделям:
SELECT CONCAT(YEAR(date), '/', WEEK(date)) AS week_name, YEAR(date), WEEK(date), COUNT(*) FROM column_name GROUP BY week_name ORDER BY YEAR(DATE) ASC, WEEK(date) ASC
Создает:
источник
ORDER BY date ASC
) тоже должно помочьРазобрался ... громоздко, но вот оно.
И, если ваши бизнес-правила гласят, что ваши недели начинаются с понедельника, измените значение
-1
на-2
.редактировать
Прошли годы, и я наконец нашел время, чтобы это написать. http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/
источник
Вы можете получить объединенный номер года и недели (200945) с помощью YEARWEEK () . Если я правильно понимаю вашу цель, это должно позволить вам сгруппировать свои многолетние данные.
Если вам нужна фактическая временная метка начала недели, это не так хорошо:
Для ежемесячного упорядочивания вы можете рассмотреть функцию LAST_DAY () - сортировка будет по последнему дню месяца, но это должно быть эквивалентно сортировке по первому дню месяца ... не так ли?
источник
Просто укажите это в избранном:
А также
источник
Если вам нужна дата окончания недели, это тоже подойдет. Это будет подсчитывать количество записей за каждую неделю. Пример: если три заказа на работу были созданы между (включительно) с 1/2/2010 по 1/8/2010 и 5 были созданы между (включительно) с 01.09.2010 по 16.01.2010, это вернет:
3 08.01.2010
5 16.01.2010
Мне пришлось использовать дополнительную функцию DATE (), чтобы обрезать поле даты и времени.
SELECT COUNT(*), DATE_ADD( DATE(wo.date_created), INTERVAL (7 - DAYOFWEEK( wo.date_created )) DAY) week_ending FROM work_order wo GROUP BY week_ending;
источник