У меня есть таблица сыгранных матчей, примерно такая:
player_id | match_id | result | opponent_rank
----------------------------------------------
82 | 2847 | w | 42
82 | 3733 | w | 185
82 | 4348 | l | 10
82 | 5237 | w | 732
82 | 5363 | w | 83
82 | 7274 | w | 6
51 | 2347 | w | 39
51 | 3746 | w | 394
51 | 5037 | l | 90
... | ... | ... | ...
Чтобы получить все выигрышные серии (не только топ-полосы любого игрока), я использую этот запрос:
SELECT player.tag, s.streak, match.date, s.player_id, s.match_id FROM (
SELECT streaks.streak, streaks.player_id, streaks.match_id FROM (
SELECT w1.player_id, max(w1.match_id) AS match_id, count(*) AS streak FROM (
SELECT w2.player_id, w2.match_id, w2.win, w2.date, sum(w2.grp) OVER w AS grp FROM (
SELECT m.player_id, m.match_id, m.win, m.date, (m.win = false AND LAG(m.win, 1, true) OVER w = true)::integer AS grp FROM matches_m AS m
WHERE matches_m.opponent_position<'100'
WINDOW w AS (PARTITION BY m.player_id ORDER BY m.date, m.match_id)
) AS w2
WINDOW w AS (PARTITION BY w2.player_id ORDER BY w2.date, w2.match_id)
) AS w1
WHERE w1.win = true
GROUP BY w1.player_id, w1.grp
ORDER BY w1.player_id DESC, count(*) DESC
) AS streaks
ORDER BY streaks.streak DESC
LIMIT 100
) AS s
LEFT JOIN player ON player.id = s.player_id
LEFT JOIN match ON match.id = s.match_id
И результат выглядит следующим образом (обратите внимание, что это не фиксированная таблица / представление, поскольку приведенный выше запрос может быть расширен определенными параметрами, такими как национальность, диапазон дат, рейтинг игроков и т. Д.):
player_id | match_id | streak
-------------------------------
82 | 3733 | 2
82 | 7274 | 3
51 | 3746 | 2
... | ... | ...
Что я хочу добавить сейчас, так это набор сводных данных, чтобы предоставить подробную информацию о победных сериях. Для начала, Я хотел бы знать средний ранг противников во время каждой из этих полос . Другими данными являются длительность серии во времени, первая и последняя дата, имя оппонента, который закончил серию или, если он все еще продолжается, и так далее. Я пробовал разные вещи - CTE, некоторые сложные объединения, объединения или добавление их в качестве функций задержки в существующем коде. Но я полностью застрял, как решить эту проблему.
Как видно из кода, мои навыки SQL очень просты, поэтому, пожалуйста, извините за любые ошибки или неэффективные утверждения. Для полного контекста я использую Postgres 9.4 в Debian, таблица match_m - это материализованное представление с 550k строками (запрос сейчас занимает 2,5 с). Данные получены из http://aligulac.com/about/db/, Я просто отразил их, чтобы создать вышеупомянутое представление.