ELO Формула в SQL-запросе - PullRequest
       22

ELO Формула в SQL-запросе

0 голосов
/ 14 сентября 2018

Это не мой первоначальный запрос, он был опубликован джентльменом по адресу http://elliot.land/. Это скрипт для системы рейтинга ELO.Проблема со мной в том, что я пробовал и пытался, но я не знаю, как преобразовать этот POSTGRESQL (RECURSIVE) в TSQL (CTE).Кто-нибудь может помочь мне с преобразованием?Вот данные:

CREATE TABLE plays (
game_number INT          NOT NULL, -- must be consecutive and start at 1!
p1name      VARCHAR(255) NOT NULL, -- first player
p1score     FLOAT        NOT NULL, -- 0 or 1
p2name      VARCHAR(255) NOT NULL, -- second player
p2score     FLOAT        NOT NULL  -- 0 or 1
);

INSERT INTO plays VALUES
(1, 'Elliot', 0, 'Brendan', 1),
(2, 'Bob', 1, 'Brendan', 0),
(3, 'Bob', 1, 'Elliot', 0),
(4, 'Jane', 1, 'Bob', 0),
(5, 'Bob', 0, 'Brendan', 1),
(6, 'Jane', 1, 'Elliot', 0);

Вот формула, где мне нужна помощь с конвертацией:

WITH RECURSIVE p(current_game_number) AS (
WITH players AS (
SELECT DISTINCT p1name AS player_name
FROM plays
UNION
SELECT DISTINCT p2name
FROM plays
)
SELECT
0               AS game_number,
player_name,
1000.0 :: FLOAT AS previous_elo,
1000.0 :: FLOAT AS new_elo
FROM players
UNION ALL
(
WITH previous_elos AS (
    SELECT *
    FROM p
)
SELECT
  plays.game_number,
  player_name,
  previous_elos.new_elo AS previous_elo,
  round(CASE WHEN player_name NOT IN (p1name, p2name)
    THEN previous_elos.new_elo
        WHEN player_name = p1name
          THEN previous_elos.new_elo + 32.0 * (p1score - (r1 / (r1 + r2)))
        ELSE previous_elos.new_elo + 32.0 * (p2score - (r2 / (r1 + r2)))          END)
FROM plays
  JOIN previous_elos
    ON current_game_number = plays.game_number - 1
  JOIN LATERAL (
       SELECT
         pow(10.0, (SELECT new_elo
                    FROM previous_elos
                    WHERE current_game_number = plays.game_number - 1 AND player_name = p1name) / 400.0) AS r1,
         pow(10.0, (SELECT new_elo
                    FROM previous_elos
                    WHERE current_game_number = plays.game_number - 1 AND player_name = p2name) / 400.0) AS r2
       ) r
    ON TRUE
 )
 )
 SELECT
 player_name,
 (
 SELECT new_elo
 FROM p
 WHERE t.player_name = p.player_name
 ORDER BY current_game_number DESC
 LIMIT 1
 )                    AS elo,
count(CASE WHEN previous_elo < new_elo
THEN 1
    ELSE NULL END) AS wins,
count(CASE WHEN previous_elo > new_elo
THEN 1
    ELSE NULL END) AS losses
FROM
(
SELECT *
FROM p
WHERE previous_elo <> new_elo
ORDER BY current_game_number, player_name
) t
GROUP BY player_name
ORDER BY elo DESC;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...