2013-08-30 2 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 | 
+--+-----+-----+---+ 

Runners данные (время) Таблица:

+------+-----+-----+ 
|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, если вы настаиваете на том, чтобы делать это в базе данных (что я бы отговорил).

Смежные вопросы