2015-12-01 2 views
3

Я знаю, что это возможно с PHP, но есть ли способ сделать это с помощью только MySQL?Как выбрать последние пять игр для каждой команды и определить выигрыш/проигрыш/связь?

У меня есть эта база данных:

------------------------------------------------------------ 
| id | hometeam | awayteam | homescore | awayscore | 
------------------------------------------------------------ 
| 1 | turtles  | muffins  | 7   | 6   | 
| 2 | cheetos  | snakes  | 8   | 1   | 
| 3 | muffins  | raspberries | 1   | 5   | 
| 4 | raspberries | snakes  | 9   | 9   | 
| 5 | muffins  | cheetos  | 2   | 9   | 
| 6 | turtles  | snakes  | 5   | 9   | 
| 7 | snakes  | turtles  | 7   | 2   | 
| 8 | muffins  | raspberries | 6   | 5   | 
| 9 | turtles  | cheetos  | 6   | 1   | 
| 10 | cheetos  | snakes  | 4   | 1   | 
| 11 | muffins  | raspberries | 1   | 5   | 
| 12 | raspberries | cheetos  | 4   | 1   | 
------------------------------------------------------------ 

Я пытаюсь вывести последние пять игр (по идентификатору DESC) для каждой команды:

------------------------------------------------------------ 
| id | team  | game1 | game2 | game3 | game4 | game5 | 
------------------------------------------------------------ 
| 1 | raspberries | win | win | loss | tie | win | 
| 2 | cheetos  | loss | win | loss | win | win | 
| 3 | muffins  | loss | win | loss | loss | loss | 
| 4 | snakes  | loss | win | win | tie | loss | 
| 5 | turtles  | win | loss | loss | win |  | 
------------------------------------------------------------ 

Как я могу это сделать?

+0

Вам нужно повернуть - проверить, например: http://stratosprovatopoulos.com/web-development/mysql/pivot-a-table-in-mysql/ –

+0

Проблемы отображения данных обычно лучше всего разрешаются на уровне презентации. Что не так с PHP? – Strawberry

ответ

1

Шаг 1 преобразовать его в более простой структуры

---------------------------------- 
| id |  team | result  | 
---------------------------------- 
| 1 | turtles  | win   | 
| 1 | muffins  | lost  | 
| 2 | cheetos  | win   | 
| 2 | snakes  | lost  | 
| 3 | muffins  | lost  | 
| 3 | raspberries | win   | 
... 

Нечто подобное

select id, 
     case rowGen.flat 
     when 0 then hometeam 
     else awayteam 
     end as team, 

     case rowGen.flat 
     when 0 and homescore < awayscore then 'win' 
     when 0 and homescore > awayscore then 'lost' 
     when 1 and homescore < awayscore then 'lost' 
     when 1 and homescore > awayscore then 'win' 
     end as result, 
from the_table, 
    (select 0 as flag 
     union all 
     select 1 as flag) as rowGen 

Затем шагу 2. Перемещение запроса выше, в качестве подвыборки к ОТ. Добавить функцию GROUP_CONCAT для групповых результатов и сократить его, чтобы оставить последнюю 5. (Вы можете добавить надлежащий порядок по идентификатору к GROUP_CONCAT)

---------------------------------------- 
| team  | last_5     | 
---------------------------------------- 
| raspberries | win,lost,win,win,lost | 
| cheetos  | win,lost,lost,win,lost | 

Выбрать, должно быть, как это

select team, 
     substring_index(group_concat(sub.result SEPARATOR ','), ',', 5) as last_5 
from (step 1 subquery) s sub 
group by team 

Шаг 3. Сплит если необходимо, поле last_5 в 5 различных полях, используя substring_index of ','.

2

Вот еще один вариант с чисто академической точки зрения.

1. Получить список команд.

select hometeam team 
from games 
union 
select awayteam team 
from games 

Промежуточные результаты:

+-------------+ 
| team  | 
+-------------+ 
| turtles  | 
| cheetos  | 
| muffins  | 
| raspberries | 
| snakes  | 
+-------------+ 

2. получить до 5 последних игр в команде, начиная с самого старого.

select team, 
     -- Adjust the game numbers when number of games is less 
     -- than 5. 
     case when count(distinct g5.id) = 1 then min(g5.id) 
      when count(distinct g4.id) = 1 then min(g4.id) 
      when count(distinct g3.id) = 1 then min(g3.id) 
      when count(distinct g2.id) = 1 then min(g2.id) 
      when count(distinct g1.id) = 1 then min(g1.id) 
     end g1, 
     case when count(distinct g4.id) = 2 then min(g4.id) 
      when count(distinct g3.id) = 2 then min(g3.id) 
      when count(distinct g2.id) = 2 then min(g2.id) 
      when count(distinct g1.id) = 2 then min(g1.id) 
     end g2, 
     case when count(distinct g3.id) = 3 then min(g3.id) 
      when count(distinct g2.id) = 3 then min(g2.id) 
      when count(distinct g1.id) = 3 then min(g1.id) 
     end g3, 
     case when count(distinct g2.id) = 4 then min(g2.id) 
      when count(distinct g1.id) = 4 then min(g1.id) 
     end g4, 
     case when count(distinct g1.id) = 5 then min(g1.id) 
     end g5 
from(  
    select hometeam team 
    from games 
    union 
    select awayteam team 
    from games 
) t 
-- Join to the games table N times for N number of games, starting with 
-- most recent (g1) to oldest (g5) 
left join games g1 on (t.team in (g1.hometeam, g1.awayteam)) 
left join games g2 on (t.team in (g2.hometeam, g2.awayteam) and g1.id < g2.id) 
left join games g3 on (t.team in (g3.hometeam, g3.awayteam) and g2.id < g3.id) 
left join games g4 on (t.team in (g4.hometeam, g4.awayteam) and g3.id < g4.id) 
left join games g5 on (t.team in (g5.hometeam, g5.awayteam) and g4.id < g5.id) 
group by team 

Промежуточные результаты:

+-------------+------+------+------+------+------+ 
| team  | g1 | g2 | g3 | g4 | g5 | 
+-------------+------+------+------+------+------+ 
| cheetos  | 12 | 10 | 9 | 5 | 2 | 
| muffins  | 11 | 8 | 5 | 3 | 1 | 
| raspberries | 12 | 11 | 8 | 4 | 3 | 
| snakes  | 10 | 7 | 6 | 4 | 2 | 
| turtles  | 9 | 7 | 6 | 1 | NULL | 
+-------------+------+------+------+------+------+ 

3. Определить результат каждой игры.

select team, 
case when team = g1.hometeam and g1.homescore > g1.awayscore then 'win' 
        when team = g1.hometeam and g1.homescore < g1.awayscore then 'loss' 
        when team = g1.awayteam and g1.homescore > g1.awayscore then 'loss' 
        when team = g1.awayteam and g1.homescore < g1.awayscore then 'win' 
        when g1.id is null then null 
        else 'tie' end 
        game1, 
case when team = g2.hometeam and g2.homescore > g2.awayscore then 'win' 
        when team = g2.hometeam and g2.homescore < g2.awayscore then 'loss' 
        when team = g2.awayteam and g2.homescore > g2.awayscore then 'loss' 
        when team = g2.awayteam and g2.homescore < g2.awayscore then 'win' 
        when g2.id is null then null 
        else 'tie' end 
        game2, 
case when team = g3.hometeam and g3.homescore > g3.awayscore then 'win' 
        when team = g3.hometeam and g3.homescore < g3.awayscore then 'loss' 
        when team = g3.awayteam and g3.homescore > g3.awayscore then 'loss' 
        when team = g3.awayteam and g3.homescore < g3.awayscore then 'win' 
        when g3.id is null then null 
        else 'tie' end 
        game3, 
case when team = g4.hometeam and g4.homescore > g4.awayscore then 'win' 
        when team = g4.hometeam and g4.homescore < g4.awayscore then 'loss' 
        when team = g4.awayteam and g4.homescore > g4.awayscore then 'loss' 
        when team = g4.awayteam and g4.homescore < g4.awayscore then 'win' 
        when g4.id is null then null 
        else 'tie' end 
        game4, 
case when team = g5.hometeam and g5.homescore > g5.awayscore then 'win' 
        when team = g5.hometeam and g5.homescore < g5.awayscore then 'loss' 
        when team = g5.awayteam and g5.homescore > g5.awayscore then 'loss' 
        when team = g5.awayteam and g5.homescore < g5.awayscore then 'win' 
        when g5.id is null then null 
        else 'tie' end 
        game5 
from(
    select team, 
      case when count(distinct g5.id) = 1 then min(g5.id) 
       when count(distinct g4.id) = 1 then min(g4.id) 
       when count(distinct g3.id) = 1 then min(g3.id) 
       when count(distinct g2.id) = 1 then min(g2.id) 
       when count(distinct g1.id) = 1 then min(g1.id) 
      end g1, 
      case when count(distinct g4.id) = 2 then min(g4.id) 
       when count(distinct g3.id) = 2 then min(g3.id) 
       when count(distinct g2.id) = 2 then min(g2.id) 
       when count(distinct g1.id) = 2 then min(g1.id) 
      end g2, 
      case when count(distinct g3.id) = 3 then min(g3.id) 
       when count(distinct g2.id) = 3 then min(g2.id) 
       when count(distinct g1.id) = 3 then min(g1.id) 
      end g3, 
      case when count(distinct g2.id) = 4 then min(g2.id) 
       when count(distinct g1.id) = 4 then min(g1.id) 
      end g4, 
      case when count(distinct g1.id) = 5 then min(g1.id) 
      end g5 
    from(  
     select hometeam team 
     from games 
     union 
     select awayteam team 
     from games 
    ) t 
    left join games g1 on (t.team in (g1.hometeam, g1.awayteam)) 
    left join games g2 on (t.team in (g2.hometeam, g2.awayteam) and g1.id < g2.id) 
    left join games g3 on (t.team in (g3.hometeam, g3.awayteam) and g2.id < g3.id) 
    left join games g4 on (t.team in (g4.hometeam, g4.awayteam) and g3.id < g4.id) 
    left join games g5 on (t.team in (g5.hometeam, g5.awayteam) and g4.id < g5.id) 
    group by team 
) r 
left join games g1 on (r.g1 = g1.id) 
left join games g2 on (r.g2 = g2.id) 
left join games g3 on (r.g3 = g3.id) 
left join games g4 on (r.g4 = g4.id) 
left join games g5 on (r.g5 = g5.id) 
order by team 

Результаты:

+-------------+-------+-------+-------+-------+-------+ 
| team  | game1 | game2 | game3 | game4 | game5 | 
+-------------+-------+-------+-------+-------+-------+ 
| cheetos  | loss | win | loss | win | win | 
| muffins  | loss | win | loss | loss | loss | 
| raspberries | win | win | loss | tie | win | 
| snakes  | loss | win | win | tie | loss | 
| turtles  | win | loss | loss | win | NULL | 
+-------------+-------+-------+-------+-------+-------+ 
+0

Хорошее решение! Голосовать! – StanislavL

+0

wow thats большой запрос ... lol thx – supercoolville

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