【问题标题】:Order by day_of_week in MySQL在 MySQL 中按 day_of_week 排序
【发布时间】:2010-11-10 17:58:29
【问题描述】:

如何通过包含星期几名称的 varchar 列对 mysql 结果进行排序?

请注意,应该先是星期一,而不是星期日。

【问题讨论】:

    标签: mysql sql sql-order-by dayofweek


    【解决方案1】:

    要么按照 Williham Totland 的建议重新设计列,要么进行一些字符串解析以获得日期表示。

    如果列包含星期几,那么您可以这样做:

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

    【讨论】:

    • 如你所知,我自己非常关注订单:(
    • 对大多数人来说可能很明显,但在输入字段名称时不要输入 。
    【解决方案2】:

    为什么不这样?

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

    我相信这个订单是周一到周日...

    【讨论】:

    • 赞成,因为这适用于我的项目,但请记住,这应该是 1 THEN 7。
    【解决方案3】:

    我认为除了重新设计列以使用枚举来代替之外,没有太多工作要做,除了在得到结果后对结果进行排序。

    编辑:一个肮脏的黑客当然是添加另一个带有 id:weekday 对的表,并在选择中使用连接或选择来伪造枚举。

    【讨论】:

      【解决方案4】:

      这看起来很乱,但仍然有效,而且看起来更通用:

      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;
      

      您还可以在存储过程中隐藏 name 到 int 的转换细节。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          我意识到这是一个旧线程,但是当它在某些搜索时间到达谷歌顶部时,我将使用它来分享我的方法。

          我想要与原始问题相同的结果,但除此之外,我还想要从一周中的当天开始对结果进行排序,然后在其余天进行。

          我创建了一个单独的表格,其中列出了两周内的日期,这样无论您从哪一天开始,您都可以运行 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;
          

          我希望这对偶然发现这篇文章的人有所帮助。

          【讨论】:

            【解决方案7】:

            找到另一种方式,您可以在一周内取消订单

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

            【讨论】:

              【解决方案8】:

              另一种方法是创建另一个包含这些天数的表和一个 int 来排序它们,在搜索时加入该表,然后按它排序。当然,不建议加入 varchar。

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

              从任何表中选择 * 在 DaysOFWeek.day 上 LEFT JOIN DaysOFWeek = WhatTable.dayColumn 按 DaysOfWeek.id 排序

              (抱歉,如果不正确;我最近一直被 SQL Server 卡住)

              同样,不建议这样做,但如果您无法更改已经获得的数据...如果 dayColumn 字段中有非标准值,这也将起作用。

              【讨论】:

                【解决方案9】:

                找到另一种适合我的方法:

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

                希望对你有帮助

                【讨论】:

                  【解决方案10】:

                  如果你试试这个,它应该可以工作:

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

                  【讨论】:

                    猜你喜欢
                    • 2013-08-24
                    • 2012-11-05
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-01-08
                    • 2010-11-21
                    • 2015-06-21
                    • 2021-09-03
                    • 1970-01-01
                    相关资源
                    最近更新 更多