SQL-запрос: найдите игру для пользователя, для которой значение current_player равно NULL, автором последней карты в игре не является пользователь, и игра не была просмотрена пользователем - PullRequest
0 голосов
/ 22 июля 2010

Краткая схема базы данных:

  • пользователей (id)
  • игры (current_player_id) // имеет много карт
  • карт (author_id, game_id, content, creation_at)
  • game_views (game_id, user_id) // показывает, какие игры видел пользователь

Мне нужно найти игру для user , которая соответствует всем правилам:

  1. current_player игры имеет значение NULL (в данный момент никто в нее не играет)
  2. автор последней карты в игре (я думаю, по порядку созданного create_at) не user
  3. игра не была замечена user

Я использую PostgreSQL.

Ответы [ 2 ]

0 голосов
/ 22 июля 2010

Я думаю, что это самое ясное решение.При правильных показателях производительность должна быть разумной, но она не будет хорошо масштабироваться, если количество игр достигнет миллионов.Если это произойдет, одним из способов повышения производительности будет сохранение последнего card_id на уровне игры.

select game_id
FROM game g
WHERE g.current_player is null
AND not exists (select 0 from game_view gv 
             where gv.user_id = v_my_user_id and gv.game_id = g.game_id)
AND not exists (select 0 from 
    (select author_id from cards c where c.game_id = g.game_id order 
    by created_at LIMIT 1) 
    t1 where t1.author_id =  v_my_user_id)
0 голосов
/ 22 июля 2010

Я пишу этот код с учетом SQL Server, но он должен работать в Postgres. Если это не так, различия должны быть минимальными.

Это решение должно работать (у меня здесь не установлен Postgres), но вы можете оптимизировать его для больших наборов данных; использовать индексы, статистику и т.д ... (как обычно).

SELECT DISTINCT games.game_id FROM games INNER JOIN cards ON games.game_id = cards.game_id  WHERE games.current_player_id is NULL and games.game_id in (SELECT DISTINCT game_id FROM GAME_VIEWS WHERE user_id != 666) and cards.author_id != 666 GROUP BY games.game_id ORDER BY cards.created_at DESC

Опять поменяйте местами "666" с фактическим идентификатором. Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...