简体   繁体   English

按 day_of_week 在 MySQL 订购

[英]Order by day_of_week in MySQL

How can I order the mysql result by varchar column that contains day of week name?如何按包含星期几名称的 varchar 列对 mysql 结果进行排序?

Note that MONDAY should goes first, not SUNDAY.请注意,MONDAY 应该排在第一位,而不是 SUNDAY。

Either redesign the column as suggested by Williham Totland, or do some string parsing to get a date representation.按照 Williham Totland 的建议重新设计列,或者进行一些字符串解析以获得日期表示。

If the column only contains the day of week, then you could do this:如果该列包含星期几,那么您可以这样做:

ORDER BY FIELD(<fieldname>, 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY');

Why not this?为什么不是这个?

ORDER BY (
    CASE DAYOFWEEK(dateField)
    WHEN 1 THEN 7 ELSE DAYOFWEEK(dateField)
    END
)

I believe this orders Monday to Sunday...我相信这是周一到周日的订单......

I'm thinking that short of redesigning the column to use an enum instead, there's not a lot to be done for it, apart from sorting the results after you've gotten them out.我认为除了重新设计列以使用枚举代替之外,除了在您得到结果后对结果进行排序之外,没有太多工作要做。

Edit: A dirty hack is of course to add another table with id:weekday pairs and using joins or select in selects to fake an enum.编辑:一个肮脏的黑客当然是添加另一个带有 id:weekday 对的表,并使用连接或选择来伪造枚举。

This looks messy but still works and seems more generic:这看起来很乱,但仍然有效,而且看起来更通用:

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;

Using if is even more generic and messier:使用 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;

You can also hide the details of conversion from name to int in stored procedure.您还可以隐藏存储过程中从 name 到 int 的转换细节。

... ORDER BY date_format(order_date, '%w') = 0, date_format(order_date, '%w') ;

找到另一种方式,您可以颠倒顺序再见周

ORDER BY date_format(date_name, '%w') DESC;

Another way would be to create another table with those days and an int to order them by, join that table when searching, and order by it.另一种方法是用那些日子和一个 int 创建另一个表来对它们进行排序,在搜索时加入该表,并按它排序。 Of course, joining on a varchar is not recommended.当然,不建议加入 varchar。

Table DaysOfWeek
id       | day
--------------------
1        | Monday
2        | Tuesday
3        | Wednesday
4        | Thursday
5        | Friday
6        | Saturday

SELECT * FROM WhateverTable LEFT JOIN DaysOFWeek on DaysOFWeek.day = WhateverTable.dayColumn ORDER BY DaysOfWeek.id SELECT * FROMWhateverTable LEFT JOIN DaysOFWeek on DaysOFWeek.day = WhatTable.dayColumn ORDER BY DaysOfWeek.id

(Apologies if that's not correct; I've been stuck with SQL server recently) (如果这不正确,请道歉;我最近一直在使用 SQL 服务器)

Again, this is NOT recommended, but if you cannot alter the data you've already got... This will also work if there are non-standard values in the dayColumn field.同样,不建议这样做,但如果您无法更改已经获得的数据......如果 dayColumn 字段中存在非标准值,这也将起作用。

Found another way that works for me:找到了另一种对我有用的方法:

SELECT LAST_NAME, HIRE_DATE, TO_CHAR(HIRE_DATE, 'fmDAY') as 'Day' FROM EMPLOYEES
ORDER BY TO_CHAR(HIRE_DATE, 'd');    

Hope it helps希望能帮助到你

In my case, since the days can be registered in several languages, to get the correct order I do like this according to Glen Solsberry :就我而言,由于可以用多种语言注册这些日子,因此根据Glen Solsberry的说法,为了获得正确的顺序,我这样做:

....
....
    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')
    ;

Do not forget that, <fieldname> is the name of the date column in question in your case.不要忘记, <fieldname>在您的情况下是相关日期列的名称。

I saw that...WHEN 1 THEN 7... was posted but it should be WHEN 1 THEN 8. So...我看到...WHEN 1 THEN 7... 已发布,但应该是 WHEN 1 THEN 8。所以...

ORDER BY ( CASE DATEPART(DW, yourdatefield) WHEN 1 THEN 8 ELSE DATEPART(DW, yourdatefield) END ) ORDER BY ( CASE DATEPART(DW, yourdatefield) WHEN 1 THEN 8 ELSE DATEPART(DW, yourdatefield) END )

Otherwise Sunday may come before Saturday because both Sunday and Saturday would equal 7. By setting Sunday to 8, it ensures it comes after Saturday.否则星期日可能会早于星期六,因为星期日和星期六都等于 7。通过将星期日设置为 8,可以确保它在星期六之后。

I realise that this is an old thread, but as it comes to the top of google for certain search times I will use it to share my approach.我意识到这是一个旧线程,但是当它在某些搜索时间出现在 google 顶部时,我将使用它来分享我的方法。

I wanted the same result as the original question, but in addition I wanted the ordering of the results starting from the current day of the week and then progressing through the rest of the days.我想要与原始问题相同的结果,但除此之外,我还希望从一周的当前日期开始对结果进行排序,然后在剩余的日子里进行排序。

I created a separate table, in which the days were listed over a fortnight, so that no matter which day you started from you could run through a sequence of 7 days.我创建了一个单独的表格,其中列出了两周内的日期,因此无论您从哪一天开始,您都可以运行 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');

I then ran the query with a variable that determined the start point in sequence and used a join to get the order number for the days.然后,我使用一个变量运行查询,该变量按顺序确定起点并使用连接来获取这些天的订单号。 For example to start the listing at Wednesday, I do the following:例如,要在星期三开始上市,我会执行以下操作:

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;

I hope this helps someone who stumbles onto this post.我希望这对偶然发现这篇文章的人有所帮助。

If you try this, it should work:如果你试试这个,它应该可以工作:

SELECT ename, TO_CHAR(hiredate, 'fmDay') as "Day" 
FROM my_table
ORDER BY MOD(TO_CHAR(hiredate, 'D') + 5, 7)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM