Сортировать по day_of_week в MySQL
Как я могу заказать результат MySQL по столбцу varchar, который содержит название дня недели?
Обратите внимание, что понедельник должен идти первым, а не воскресенье.
12 ответов
Либо перепроектируйте столбец в соответствии с предложением Виллихема Тотланда, либо выполните синтаксический анализ строки, чтобы получить представление даты.
Если столбец содержит только день недели, вы можете сделать это:
ORDER BY FIELD(<fieldname>, 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY');
Почему не это?
ORDER BY (
CASE DAYOFWEEK(dateField)
WHEN 1 THEN 7 ELSE DAYOFWEEK(dateField)
END
)
Я считаю, что это заказы с понедельника по воскресенье...
Я думаю, что если не изменять дизайн столбца для использования перечисления, то для этого не нужно ничего делать, кроме сортировки результатов после того, как вы их получили.
Редактировать: грязный хак, конечно, это добавить еще одну таблицу с id: пары дней недели и с помощью объединений или выбора в выборках, чтобы подделать перечисление.
... ORDER BY date_format(order_date, '%w') = 0, date_format(order_date, '%w');
Нашел другой способ, вы можете изменить порядок до свидания неделю
ORDER BY date_format(date_name, '%w') DESC;
Это выглядит грязно, но все еще работает и кажется более общим:
select day,
case day
when 'monday' then 1
when 'tuesday' then 2
when 'wednesday' then 3
when 'thursday' then 4
when 'friday' then 5
when 'saturday' then 6
when 'sunday' then 7
end as day_nr from test order by day_nr;
Использование if является еще более общим и сложным:
select id, day,
if(day = 'monday',1,
if(day = 'tuesday',2,
if(day = 'wednesday',3,
if(day = 'thursday',4,
if(day = 'friday',5,
if(day = 'saturday',6,7)
)
)
)
)
) as day_nr from test order by day_nr;
Вы также можете скрыть детали преобразования имени в int в хранимой процедуре.
Я понимаю, что это старая ветка, но так как она подходит к вершине Google в течение определенного времени поиска, я буду использовать ее, чтобы поделиться своим подходом.
Я хотел получить тот же результат, что и в исходном вопросе, но кроме того, я хотел упорядочить результаты, начиная с текущего дня недели, а затем продвигаться до конца дня.
Я создал отдельную таблицу, в которой дни были перечислены в течение двух недель, чтобы независимо от того, с какого дня вы начинали, вы могли проходить последовательность из 7 дней.
CREATE TABLE IF NOT EXISTS `Weekdays` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=15 ;
INSERT INTO `Weekdays` (`id`, `name`) VALUES
(1, 'Monday'),
(2, 'Tuesday'),
(3, 'Wednesday'),
(4, 'Thursday'),
(5, 'Friday'),
(6, 'Saturday'),
(7, 'Sunday'),
(8, 'Monday'),
(9, 'Tuesday'),
(10, 'Wednesday'),
(11, 'Thursday'),
(12, 'Friday'),
(13, 'Saturday'),
(14, 'Sunday');
Затем я запустил запрос с переменной, которая определила начальную точку в последовательности, и использовал соединение, чтобы получить номер заказа для дней. Например, чтобы начать листинг в среду, я делаю следующее:
SELECT @startnum := MIN(id) FROM Weekdays WHERE name='Wednesday';
SELECT * FROM Events INNER JOIN ( SELECT id as weekdaynum, name as dayname FROM Weekdays WHERE id>(@startnum-1) AND id<(@startnum+7) ) AS s2 ON s2.dayname=Events.day ORDER BY weekdaynum;
Надеюсь, это поможет тому, кто наткнется на этот пост.
Другим способом было бы создать еще одну таблицу с этими днями и целое число, чтобы упорядочить их, присоединиться к этой таблице при поиске и упорядочить по ней. Конечно, присоединение к varchar не рекомендуется.
Table DaysOfWeek
id | day
--------------------
1 | Monday
2 | Tuesday
3 | Wednesday
4 | Thursday
5 | Friday
6 | Saturday
ВЫБЕРИТЕ * ОТ КАКИХ-ЛИБО СЛЕДУЮЩИХ ПРИСОЕДИНЯЙТЕСЬ К DaysOFWeek на DaysOFWeek.day = WhwhatTable.dayColumn ORDER BY DaysOfWeek.id
(Извините, если это не правильно; я недавно застрял на SQL-сервере)
Опять же, это НЕ рекомендуется, но если вы не можете изменить уже полученные данные... Это также будет работать, если в поле dayColumn есть нестандартные значения.
Нашел другой способ, который работает для меня:
SELECT LAST_NAME, HIRE_DATE, TO_CHAR(HIRE_DATE, 'fmDAY') as 'Day' FROM EMPLOYEES
ORDER BY TO_CHAR(HIRE_DATE, 'd');
Надеюсь, поможет
Я видел, что ... КОГДА 1, ТОГДА 7 ... было опубликовано, но это должно быть КОГДА 1, ТОГДА 8. Итак...
ORDER BY (CASE DATEPART(DW, yourdatefield)WHEN 1 THEN 8 ELSE DATEPART(DW, yourdatefield) END )
В противном случае воскресенье может наступить перед субботой, потому что и воскресенье, и суббота будут равны 7. Установив воскресенье равным 8, он гарантирует, что оно наступит после субботы.
В моем случае, поскольку дни могут быть зарегистрированы на нескольких языках, чтобы получить правильный порядок, я делаю это в соответствии с user16645:
....
....
ORDER BY
FIELD(<fieldname>, 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY'),
FIELD(<fieldname>, 'LUNDI', 'MARDI', 'MERCREDI', 'JEUDI', 'VENDREDI', 'SAMEDI', 'DIMANCHE'),
FIELD(<fieldname>, 'LUNES', 'MARTES', 'MIERCOLES', 'JUEVES', 'VIERNES', 'SABADO', 'DOMINGO'),
FIELD(<fieldname>, 'MONTAGE', 'DIENSTAG', 'MITTWOCH', 'DENNERSTAG', 'FREITAG', 'SAMSTAG', 'SONNTAG')
;
Не забудь об этом,<fieldname>
- это имя столбца даты, о котором идет речь в вашем случае.
Если вы попробуете это, оно должно работать:
SELECT ename, TO_CHAR(hiredate, 'fmDay') as "Day"
FROM my_table
ORDER BY MOD(TO_CHAR(hiredate, 'D') + 5, 7)