2012-01-17 60 views
1

我已經繼承了一個跟蹤曲棍球聯賽的比賽結果的應用程序。結果表格如下所示:優化體育現場排名查詢

[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

解決這個問題的另一種方法是分別彙總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 
+0

謝謝,我來看看這個。 – ScottE 2012-01-17 15:13:49

+0

你試過這個嗎?不爲我工作。 – ScottE 2012-01-17 15:42:44