2013-08-30 63 views
1

我有三個表(亞軍,階段和時間)MySQL的 - 排序結果由總時間

運動員表:

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

你看過連接嗎? – Maximus2012

回答

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

這需要一個連接,然後條件聚合。最後一列使用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表。讓它們動態化會使查詢變得更加複雜。

+0

對不起,我的想法是做一個foreach循環來創建查詢,所以你不要過度使用MySQL。 –

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

桌子是動態的... –

1

你可能需要做大量的內側連接,subquerying的,如果你想要去與該模式比較這個時間與那個時候,它真的不會漂亮。或者,如果你的階段是固定的,你可以簡化爲一個表,每列作爲一個階段。如果階段的數量和名字需要改變(無論出於何種原因),那麼我建議在你的亞軍日期/時間表中存儲開始時間和結束時間。

如果您的階段是固定的,那麼直接從數據庫中獲得結果將很容易。如果這些階段可能會有所不同(取決於您的站點用戶配置階段),那麼您將需要在PHP中交叉選擇數據,或者如果您堅持在數據庫中執行此操作(我會勸阻),請查看this SO question