MySQL SELECT из нескольких таблиц, нескольких GROUP BY и group_concat?

У меня есть три таблицы, которые я хочу запросить в MySQ. Следующим образом:

**Table: Leaderboard**
Name  | Score
------------
James | 1
Steve | 2
Dave  | 5

**Table: Actions**
Name  | Action       | Time
----------------------------
James | Ate an apple | 01:00
James | Kicked a dog | 02:00
Steve | Ate a dog    | 03:00
Steve | Kicked a hen | 01:00
Dave  | died         | 02:00

**Table: Items**
Name  | Item         | Time
----------------------------
James | Chainsaw     | 01:00
James | Hammer       | 01:05
James | Crowbar      | 01:10
Steve | Hammer       | 02:00
Steve | Egg          | 01:05
Dave  | Egg          | 01:05

Мне нужен запрос, который выбирает каждого игрока (ORDER BY Leaderboard.score DESC) и выбирает их последнее действие WHERE Actions.action LIKE 'Ate %', а затем дает все Items.Item ORDER BY Time DESC

Так, например, вывод будет выглядеть так

**Output**
Name   | Latest_Action | Items
Steve  | Ate a dog     | Hammer, Egg
James  | Ate an apple  | Crowbar, Hammer, Chainsaw

До сих пор я пробовал следующий запрос, но он возвращает каждый элемент несколько раз в group_concat

SELECT Leaderboard.Name, Actions.*, group_concat(Items.Item)
FROM Leaderboard, Actions, Items
WHERE Items.Name = Actions.Name
  AND Actions.Action LIKE 'Ate %'
  AND Actions.Name IN (SELECT Name FROM Leaderboard ORDER BY SCORE DESC)
GROUP BY Leaderboard.name

Любая помощь высоко ценится!


person lufc    schedule 10.07.2012    source источник
comment
Ваше использование подзапроса для сортировки результата не сработает: внешний GROUP BY переопределит любую существующую сортировку.   -  person MvG    schedule 10.07.2012


Ответы (1)


SELECT Leaderboard.Name,
  (SELECT Actions.Action
   FROM Actions
   WHERE Actions.Name = Leaderboard.Name
     AND Actions.Action LIKE 'Ate%'
   ORDER BY Time DESC
   LIMIT 1
  ) AS Latest_Action,
  GROUP_CONCAT(Items.Item
               ORDER BY Items.Time DESC
               SEPARATOR ', '
              ) AS Items
FROM Leaderboard
     LEFT JOIN Items ON Leaderboard.Name = Items.Name
GROUP BY Leaderboard.Name
HAVING Latest_Action IS NOT NULL
ORDER BY Leaderboard.Score DESC

Результат проверен в SQL Fiddle.

person MvG    schedule 10.07.2012
comment
Сделай так: GROUP_CONCAT(Items.Item SEPARATOR ', ' ORDER BY Items.Time DESC) - person ypercubeᵀᴹ; 10.07.2012
comment
@ypercube: Спасибо, пропустил эту часть. - person MvG; 10.07.2012
comment
Это работает точно так, как просили, большое спасибо. Как выбрать несколько столбцов из таблицы действий? - person lufc; 10.07.2012
comment
@ user1491032: Обсуждение этого вопроса выходит за рамки такого комментария, особенно с точки зрения возможностей форматирования исходного кода. Лучше задать следующий вопрос об этом. - person MvG; 10.07.2012