0

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

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

在 PHP 中,这相当容易:

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

但是,如果我有一个从 10 点开始并且距离 1 小时的事件,以及一个从 11 点开始并且距离 3 小时的事件,那么使用 MySQLORDER BY EventStart时,事件将显示在 8 时间之前列出的 9 个出发时间,这很明显不正确。

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

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

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

谢谢你的帮助!

4

2 回答 2

1

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

像这样的东西应该工作。我认为,我已将其拆分为子查询,以使每个步骤更具可读性。

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;

链接到 SQLFiddle

于 2013-06-18T18:39:34.547 回答
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
于 2013-06-18T18:05:03.433 回答