Я пытаюсь (и не могу) объединить некоторые таблицы в базе данных SQLite.Сами данные сложны, но я думаю, что сводил их к иллюстративному примеру.
Вот три таблицы, к которым я хочу присоединиться.
Таблица: События
+----+---------+-------+-----------+
| id | user_id | class | timestamp |
+----+---------+-------+-----------+
| 1 | 'user1' | 6 | 100 |
| 2 | 'user1' | 12 | 400 |
| 3 | 'user1' | 4 | 900 |
| 4 | 'user2' | 6 | 400 |
| 5 | 'user2' | 3 | 800 |
| 6 | 'user2' | 8 | 900 |
+----+---------+-------+-----------+
Таблица: Игры
+---------+---------+------------+-----------+
| user_id | game_id | game_class | timestamp |
+---------+---------+------------+-----------+
| 'user1' | 1 | 'A' | 200 |
| 'user2' | 2 | 'A' | 300 |
| 'user1' | 3 | 'B' | 500 |
| 'user1' | 4 | 'A' | 600 |
| 'user1' | 5 | 'A' | 700 |
+---------+---------+------------+-----------+
Таблица: AScores
+---------+-------+
| game_id | score |
+---------+-------+
| 1 | 8 |
| 2 | 2 |
| 4 | 9 |
| 5 | 6 |
+---------+-------+
Я бы хотел присоединиться к этимпредоставить дополнительный столбец в первой таблице, содержащий текущий счет пользователей в игровом классе A на момент события.Т.е. я хотел бы, чтобы результат объединения выглядел так:
Желаемый результат
+----+----------+-------+-----------+-----------------+
| id | user_id | class | timestamp | current_a_score |
+----+----------+-------+-----------+-----------------+
| 1 | 'user1' | 6 | 100 | (null) |
| 2 | 'user1' | 12 | 400 | 8 |
| 3 | 'user1' | 4 | 900 | 6 |
| 4 | 'user2' | 6 | 400 | 2 |
| 5 | 'user2' | 3 | 800 | 2 |
| 6 | 'user2' | 8 | 900 | 2 |
+----+----------+-------+-----------+-----------------+
Следующее простое объединение объединяет две таблицы AScores и Games.
SELECT * FROM AScores
INNER JOIN Games
ON AScores.game_id = Games.game_id
И поэтому я надеялся присоединить это к таблице событий в качестве подзапроса.Примерно так:
SELECT Events.*, AScoredGames.time_stamp AS game_time_stamp, AScoredGames.score
FROM Events
LEFT OUTER JOIN (
SELECT AScores.score, Games.* FROM AScores
INNER JOIN Games
ON AScores.game_id = Games.game_id
) AS AScoredGames
ON Events.user_id = AScoredGames.user_id
AND Events.time_stamp >= AScoredGames.time_stamp
ORDER BY Events.time_stamp ASC
Это приводит к следующему:
+----+---------+-------+------------+-----------------+-------+
| id | user_id | class | time_stamp | game_time_stamp | score |
+----+---------+-------+------------+-----------------+-------+
| 1 | user1 | 6 | 100 | NULL | NULL |
| 2 | user1 | 12 | 400 | 200 | 8 |
| 4 | user2 | 6 | 400 | 300 | 2 |
| 5 | user2 | 3 | 800 | 300 | 2 |
| 6 | user2 | 8 | 900 | 300 | 2 |
| 3 | user1 | 4 | 900 | 200 | 8 |
| 3 | user1 | 4 | 900 | 600 | 9 |
| 3 | user1 | 4 | 900 | 700 | 6 |
+----+---------+-------+------------+-----------------+-------+
Поэтому мне нужно сгруппировать по Events.id, чтобы избавиться от тройной строки с помощью Events.id 3.Но я хочу выбрать строку с максимальным значением game_time_stamp, а затем использовать счет строки.Если я использую MAX (game_time_stamp) в качестве агрегации, мне все равно придется самостоятельно агрегировать счет.Есть ли способ связать выбор строки в функции агрегации столбца счета с результатом функции агрегации столбца game_time_stamp?
(NB. Существующие ответы на такие вопросы, как Выберите первую запись в One-to-Многие отношения, использующие левое соединение и SQL Server: как присоединиться к первой строке , похоже, не позволяют и говорят, что нужно использовать предложение WHERE для подзапроса. Но я борюсь с этим (Я опубликую еще один вопрос об этом), и я могу придумать хотя бы одно решение, и я надеюсь, что есть лучшие.)