我在MySQL表中有两列:EventStart和Distance。 EventStart是一个DateTime,它表示事件开始的时间,而Distance是一个字符串,它将到事件的英里数与到达事件的时间结合起来,例如“ 126.2英里/ 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事件将显示8点之前列出的9个离开时间,这显然是不正确的。

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


如何仅选择“ /”标记之后的所有内容进行距离计算?
如何从EventStart中减去该值,以便可以对计算出的距离进行排序?


最后一点:我知道用这种方式存储距离是一个错误;我正在别人那里接项目。

谢谢你的帮助!

最佳答案

好吧,那有点有趣。我希望您首先找到创建此模式的人,并向他们展示他们应得的爱。

这样的事情应该起作用。我认为,我已将其拆分为子查询,以使每个步骤的可读性更高。

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

09-25 22:06