Php MySQL-按总时间对结果排序

Php MySQL-按总时间对结果排序,php,mysql,sql,Php,Mysql,Sql,我有三张桌子(跑步者、舞台和时间) 跑步者表: +--+----+ |id|name| +--+----+ |1 |Karl| +--+----+ |2 |Lou | +--+----+ 阶段表: +--+-----+-----+---+ |id|name |order|end| +--+-----+-----+---+ |1 |start| 1 | 0 | +--+-----+-----+---+ |2 |bike | 2 | 0 | +--+-----+-----+---+ |3

我有三张桌子(跑步者、舞台和时间)

跑步者表:

+--+----+
|id|name|
+--+----+
|1 |Karl|
+--+----+
|2 |Lou |
+--+----+
阶段表:

+--+-----+-----+---+
|id|name |order|end|
+--+-----+-----+---+
|1 |start|  1  | 0 |
+--+-----+-----+---+
|2 |bike |  2  | 0 |
+--+-----+-----+---+
|3 |run  |  3  | 0 |
+--+-----+-----+---+
|4 |end  |  4  | 1 |
+--+-----+-----+---+
跑步者数据(时间)表:

嗯。。。现在我想得到的结果如下(按总时间排序):

+------+-----+-----+-----+-----+----------+
|跑步者|开始|自行车|跑步|结束|总计|
+------+-----+-----+-----+-----+----------+
|Karl | 10:00 | 10:30 | 11:00 | 12:14 | 01:44:00 |以下各项应有效(时间单位为秒,而非HH:MM:SS)

(如果您发布创建表,或者更好地使用此工具:这将使我们更容易测试我们的语句)

以下内容应该可以工作(时间以秒为单位,而不是以HH:MM:SS为单位)


(如果您发布创建表,或者更好地使用此工具:它将使我们更容易测试语句)

这需要一个连接,然后是条件聚合。最后一列使用
timediff()
减去两次:

select r.name,
       max(case when rt.stage = 1 then rt.time end) as start,
       max(case when rt.stage = 2 then rt.time end) as walk,
       max(case when rt.stage = 3 then rt.time end) as bike,
       max(case when rt.stage = 4 then rt.time end) as end,
       timediff(max(case when rt.stage = 4 then rt.time end),
                max(case when rt.stage = 1 then rt.time end)
               ) as TotalTime
from RunnersTime rt join
     Runners r
     on rt.runner = r.id 
group by r.id
order by TotalTime;

请注意,列名是固定的,因此不使用
stages
表。使它们动态化将使查询更加复杂。

这需要一个连接,然后是条件聚合。最后一列使用
timediff()
减去两次:

select r.name,
       max(case when rt.stage = 1 then rt.time end) as start,
       max(case when rt.stage = 2 then rt.time end) as walk,
       max(case when rt.stage = 3 then rt.time end) as bike,
       max(case when rt.stage = 4 then rt.time end) as end,
       timediff(max(case when rt.stage = 4 then rt.time end),
                max(case when rt.stage = 1 then rt.time end)
               ) as TotalTime
from RunnersTime rt join
     Runners r
     on rt.runner = r.id 
group by r.id
order by TotalTime;

请注意,列名是固定的,因此不使用
stages
表。使其动态化将使查询更加复杂。

查询看起来像这样,但计算总数的方法取决于时间的数据类型

select runners.name as runner, starttime.time as start, biketime.time as bike, runtime.time as run, endtime.time as end, endtime.time - starttime.time as Total

from runners

inner join time as starttime on runners.id = starttime.runner
inner join stages as startstages on starttime.stage = startstages.id and startstages.name = 'start'

inner join time as biketime on runners.id = biketime.runner
inner join stages as bikestages on biketime.stage = bikestages.id and bikestages.name = 'bike'

inner join time as runtime on runners.id = runtime.runner
inner join stages as runstages on runtime.stage = runstages.id and runstages.name = 'run'

inner join time as endtime on runners.id = endtime.runner
inner join stages as endstages on endtime.stage = endstages.id and endstages.name = 'end'

order by endtime.time - starttime.time

查询看起来像这样,但是计算总数的方法取决于时间的数据类型

select runners.name as runner, starttime.time as start, biketime.time as bike, runtime.time as run, endtime.time as end, endtime.time - starttime.time as Total

from runners

inner join time as starttime on runners.id = starttime.runner
inner join stages as startstages on starttime.stage = startstages.id and startstages.name = 'start'

inner join time as biketime on runners.id = biketime.runner
inner join stages as bikestages on biketime.stage = bikestages.id and bikestages.name = 'bike'

inner join time as runtime on runners.id = runtime.runner
inner join stages as runstages on runtime.stage = runstages.id and runstages.name = 'run'

inner join time as endtime on runners.id = endtime.runner
inner join stages as endstages on endtime.stage = endstages.id and endstages.name = 'end'

order by endtime.time - starttime.time

如果您想使用该模式,您可能需要进行大量的内部连接、子查询,并比较这一次和那一次,这真的不太好。或者,如果您的阶段是固定的,您可以简化为一个表,每列作为一个阶段。如果阶段的数量和名称需要改变(无论出于何种原因),那么我建议在跑步者日期/时间表中存储开始时间和结束时间


如果你的阶段是固定的,那么直接从数据库中获得你想要的结果将很容易。如果阶段可能不同(例如,取决于站点用户配置的阶段),那么您将需要在PHP中交叉标记您的数据,或者查看您是否坚持在数据库中这样做(我不鼓励这样做)。

您可能需要做很多内部连接、子查询,如果你想使用这个模式,比较一下这一次和那一次,那就真的不太好了。或者,如果您的阶段是固定的,您可以简化为一个表,每列作为一个阶段。如果阶段的数量和名称需要改变(无论出于何种原因),那么我建议在跑步者日期/时间表中存储开始时间和结束时间


如果你的阶段是固定的,那么直接从数据库中获得你想要的结果将很容易。如果阶段可能不同(例如,取决于您的站点用户配置的阶段),那么您需要在PHP中交叉标记您的数据,或者查看您是否坚持在数据库中这样做(我不鼓励这样做)。

您查看过联接吗?您查看过联接吗?对不起,我的想法是执行foreach循环来创建查询,对不起,我的想法是做一个foreach循环来创建查询,这样你就不会过度使用MySQL了。
select runners.name as runner, starttime.time as start, biketime.time as bike, runtime.time as run, endtime.time as end, endtime.time - starttime.time as Total

from runners

inner join time as starttime on runners.id = starttime.runner
inner join stages as startstages on starttime.stage = startstages.id and startstages.name = 'start'

inner join time as biketime on runners.id = biketime.runner
inner join stages as bikestages on biketime.stage = bikestages.id and bikestages.name = 'bike'

inner join time as runtime on runners.id = runtime.runner
inner join stages as runstages on runtime.stage = runstages.id and runstages.name = 'run'

inner join time as endtime on runners.id = endtime.runner
inner join stages as endstages on endtime.stage = endstages.id and endstages.name = 'end'

order by endtime.time - starttime.time