我有三张桌子(跑步者,阶段和时间)
跑步者表:
+--+----+
|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 )
+------+-----+-----+-----+-----+----------+
知道如何才能做到这一点吗? 问候!
答案 0 :(得分: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/这将使我们更容易测试我们的陈述)
答案 1 :(得分: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
表。使它们动态化将使查询更加复杂。
答案 2 :(得分: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
答案 3 :(得分:1)
你可能需要进行大量的内部加入,子查询,并比较这个时间与那个时间,如果你想要使用该模式,它真的不会很漂亮。或者,如果你的阶段是固定的,你可以简化为一个表,每列作为一个阶段。如果阶段的数量和名称需要变化(无论出于何种原因),那么我建议在赛跑者日期/时间表中存储开始时间和结束时间。
如果您的阶段已修复,那么直接从数据库中获取结果将很容易。如果阶段可能会有所不同(例如,取决于您的站点用户配置阶段),那么您将需要在PHP中交叉选择数据,或者如果您坚持在数据库中执行此操作,请查看this SO question(我d劝阻)。