MySQL:在选择查询中操作日期和字符串

时间:2013-06-18 17:44:16

标签: php mysql string date datetime

我在MySQL表中有两列:EventStart和Distance。 EventStart是一个DateTime,表示事件开始的时间,但Distance是一个字符串,它将事件的里程数与到达事件的时间相结合,例如“126.2 mi / 2小时35分钟”。

我想根据我需要离开事件的时间来打印表的内容,这意味着我要从EventStart中减去Distance值的右半部分(“/”标记后面的所有内容)。我想按出发时间订购结果,所以当我迭代结果时,我只需打印它们。

在PHP中,这很容易:

$distance = substr($row['Distance'], strrpos( $row['Distance'],'/')+1);
$result = date('j M - g:i a', strtotime($row['EventStart']." -".$distance));

但是,如果我有一个事件从10开始并且距离1个小时,并且一个事件从11开始并且距离3个小时,那么拥有MySQL ORDER BY EventStart将显示事件列出的9个出发时间在8次之前,这显然是不正确的。

由于可能有100个条目,我想避免制作2D PHP数组并对其进行排序,所以我希望直接在MySQL查询中进行。我认为这是一个两部分问题:

  1. 如何选择距离计算“/”标记后的所有内容?
  2. 如何从EventStart中减去该值,以便我可以按计算的距离进行排序?
  3. 最后一点:我知道以这种方式存储距离是一个错误;我正在接收别人的项目。

    感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

嗯,这有点儿有趣。我希望你能找到谁首先创建了这个模式并向他们展示了他们应得的爱。

这样的事情应该有效。我认为,我已将它拆分为subQueries,以使每一步都更具可读性。

SELECT miles, hours + minutes FROM (
SELECT
  cast(left(Distance, first_space) AS DECIMAL(5,2)) AS miles,
  cast(substr(Distance, distance_split_loc+1, hour_loc-distance_split_loc-1) AS unsigned) * 60 AS hours,
  cast(IF (hour_loc = 0,
    substr(Distance, distance_split_loc+1, min_loc-distance_split_loc-1),
    substr(Distance, space_after_hour, min_loc-space_after_hour)) AS unsigned) AS minutes
FROM
(SELECT
   Distance,
   locate(' ', Distance) first_space,
   locate('/', Distance) distance_split_loc,
   locate('hour', Distance) AS hour_loc,
   locate('min', Distance) AS min_loc,
   locate(' ',Distance,locate('hour', Distance)) AS space_after_hour
 FROM distance) AS temp_table) AS timecalc
ORDER BY miles;

Link to SQLFiddle

答案 1 :(得分:0)

你必须进行字符串操作才能获得时间和分钟。以下是假设出现“小时”和“分钟”两小时的小时数:

select (substring(val, instr(val, '/')+2)+0) +  as hours,
       (substring(val, instr(val, 'mins')-3)+0) / 60
from (select '126.2 mi / 2 hours 5 mins' as val) t