Оптимизировать запрос рейтинга спортивных сайтов - PullRequest
1 голос
/ 17 января 2012

Я унаследовал приложение, которое отслеживает результаты игр для хоккейной лиги.Таблица результатов выглядит следующим образом:

[dbo].[league_division_games](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [division] [int] NULL,
    [team1] [int] NULL,
    [team1_score] [int] NULL,
    [team2] [int] NULL,
    [team2_score] [int] NULL,
    [shootout] [bit] NOT NULL)

Существующий запрос - неприятный курсор, который работает ужасно.Я даже не буду публиковать это здесь!

Я начал переписывать это, но это выглядит довольно глупо для меня.

SELECT
    teams.id
    ,teams.name
    ,IsNull(COUNT(games.id), 0) AS GP
    ,SUM(CASE WHEN (teams.id = games.team1 AND games.team1_score > games.team2_score) OR (teams.id = games.team2 AND games.team2_score > games.team1_score) THEN 1 ELSE 0 END) AS W
    ,SUM(CASE WHEN (teams.id = games.team1 AND games.team1_score < games.team2_score) OR (teams.id = games.team2 AND games.team2_score < games.team1_score) THEN 1 ELSE 0 END) AS L
    ,SUM(CASE WHEN (teams.id = games.team1 AND games.team1_score = games.team2_score) OR (teams.id = games.team2 AND games.team1_score = games.team2_score) THEN 1 ELSE 0 END) AS T
FROM
    dbo.league_division_teams teams
    LEFT OUTER JOIN dbo.league_division_games games ON teams.id = games.team1 OR teams.id = games.team2
WHERE
    teams.division = @DIV
GROUP BY
    teams.id,
    teams.name

По сути, я должен продолжать проверять каждую сторону счета на предмет побед, поражений, связей, целей против, целей для.

Один бит сложности - в хоккее, если это сверхурочные потери, считайте 1 очко для проигравшего и 2 для победителя.Кроме того, если это перестрелка, то цели для равняются наименьшему из двух баллов.

По этим причинам совокупные заявления о делах станут достаточно большими и, вероятно, не будут работать хорошо.

Я подумывал о создании CTE, чтобы немного сгладить это, но еще не пошел по этому пути.

Кто-нибудь подходил к этому по-другому?Я думаю, что эти виды статистики довольно распространены.

Спасибо.

1 Ответ

1 голос
/ 17 января 2012

Еще один способ приблизиться к этому - просто объединить 2 «стороны» отдельно и объединить их в конце. Вам нужно немного поиграть с ним, чтобы увидеть, работает ли он лучше, но я думаю что-то вроде этого:

select
    id, name, sum(gp), sum(w), sum(l), sum(t)
from (
    SELECT
        teams.id
        ,teams.name
        ,IsNull(COUNT(games.id), 0) AS GP
        ,CASE WHEN team1_score > team2_score THEN 1 ELSE 0 END AS W
        ,CASE WHEN team1_score < team2_score THEN 1 ELSE 0 END AS L
        ,CASE WHEN team1_score = team2_score THEN 1 ELSE 0 END AS T
    FROM
        dbo.league_division_teams teams
        LEFT OUTER JOIN dbo.league_division_games games ON teams.id = games.team1 

    union

    SELECT
        teams.id
        ,teams.name
        ,IsNull(COUNT(games.id), 0) AS GP
        ,CASE WHEN team2_score > team1_score THEN 1 ELSE 0 END AS W
        ,CASE WHEN team2_score < team1_score THEN 1 ELSE 0 END AS L
        ,CASE WHEN team2_score = team1_score THEN 1 ELSE 0 END AS T
    FROM
        dbo.league_division_teams teams
        LEFT OUTER JOIN dbo.league_division_games games ON teams.id = games.team2
)
group by
    id, name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...