5

我面临根据 AM / PM 排序的问题。

这是我的表格数据

login_time
1:30 PM
2:00 AM
8:00 AM
9:30 PM
10:00 PM
11:10 AM

我希望结果为:

login_time
2:00 AM
8:00 AM
11:10 AM
1:30 PM
9:30 PM
10:00 PM

我怎样才能做到这一点?

4

4 回答 4

16

您可以使用STR_TO_DATE函数,如果您愿意,也可以使用TIME()仅提取时间部分:

SELECT
  login_time
FROM
  tablename
ORDER BY
  STR_TO_DATE(login_time, '%l:%i %p')

在此处查看小提琴。

于 2013-08-07T17:59:37.660 回答
5

如果您已经将日期设置为VARCHAR,我建议您将其重构为一TIME列。这可以很容易地在网上完成:

UPDATE tablename SET login_time = STR_TO_DATE(login_time, '%l:%i %p');
ALTER TABLE tablename CHANGE login_time login_time TIME;

我在TIME这里使用类型,因为您的数据显然只包含time。也许一种DATETIME类型是最合适的。有关各种选项,请参阅http://dev.mysql.com/doc/refman/5.5/en/date-and-time-types.html

无论如何,一旦将列重构为适当的类型,您就可以编写:

SELECT
  login_time
FROM
  tablename
ORDER BY
  login_time

有了额外的好处,现在您可以建立索引login_time来加快搜索/排序:

ALTER TABLE tablename ADD INDEX ( login_time );

http://sqlfiddle.com/#!2/03991/1(点击“查看执行计划”查看实际索引已被使用)。

于 2013-08-07T18:24:20.723 回答
1

只需在您的 ORDER BY 子句中使用多个表达式,首先按 AM/PM 排序,然后按第 12 小时特殊情况排序,然后按小时排序,其余时间按分钟排序。

ORDER BY
  RIGHT(login_time, 2),
  CASE
    WHEN 12 = convert(int, REPLACE(LEFT(login_time, 2), ':', '')) THEN 1
    ELSE 2
  END,
  convert(int, REPLACE(LEFT(login_time, 2), ':', '')),
  login_time
于 2013-08-07T17:47:40.013 回答
1

就像提到的评论一样,如果可能的话 - 更改列的数据类型。如果转换值超出您的控制顺序:

select login_time from table order by CAST(login_time as datetime)
于 2013-08-07T17:51:28.730 回答