1

我有三张桌子(跑步者、阶段和时间)

跑者表:

+--+----+
|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 |
+--+-----+-----+---+

跑者数据(时间)表:

+------+-----+-----+
|runner|stage|time |
+------+-----+-----+
|   1  |  1  |10:00|
+------+-----+-----+
|   1  |  2  |10:30|
+------+-----+-----+
|   1  |  3  |11:00|
+------+-----+-----+
|   2  |  1  |10:00|
+------+-----+-----+
|   2  |  2  |10:43|
+------+-----+-----+
|   2  |  3  |11:56|
+------+-----+-----+
|   1  |  4  |12:14|
+------+-----+-----+
|   2  |  4  |12:42|
+------+-----+-----+

嗯......那么我现在想要的是得到如下结果(按总时间排序):

+------+-----+-----+-----+-----+----------+
|runner|start|bike |run  | end |   Total  |
+------+-----+-----+-----+-----+----------+
| Karl |10:00|10:30|11:00|12:14| 01:44:00 |   <--- FIRST( one hour)
+------+-----+-----+-----+-----+----------+
| Lou  |10:30|10:30|11:56|12:42| 02:12:00 |   <--- SECONDS( two hours )
+------+-----+-----+-----+-----+----------+

知道我怎么能做到这一点吗?问候!

4

4 回答 4

1

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

如果您的阶段是固定的,那么直接从数据库中获取您正在寻找的结果将很容易。如果阶段可能会有所不同(例如,取决于您的站点用户配置阶段),那么您将需要在 PHP 中交叉表您的数据,或者如果您坚持在数据库中执行此操作,请查看这个 SO 问题(我不鼓励这样做) )。

于 2013-08-30T22:31:14.547 回答
1

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

select r.name, rd_start.time as start, rd_bike.time as bike, rd_run.time as run, rd_end.time as end,  from runner as r, rd_start.time+rd_bike.time+rd_run.time+rd_end.time as total
inner join runnerdata as rd_start on r.id=rd_start.runner and rd_start.stage=1
inner join runnerdata as rd_bike on r.id=rd_bike.runner and rd_start.stage=2
inner join runnerdata as rd_run on r.id=rd_run.runner and rd_start.stage=3
inner join runnerdata as rd_end on r.id=rd_end.runner and rd_start.stage=4
order by (rd_start.time+rd_bike.time+rd_run.time+rd_end.time)

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

于 2013-08-30T21:52:36.307 回答
1

这需要一个连接,然后是条件聚合。最后一列用于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不使用该表。使它们动态化会使查询更加复杂。

于 2013-08-30T21:53:32.987 回答
1

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

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
于 2013-08-30T21:57:13.357 回答