2012-09-14 55 views
3

我有以下表格:計數連接表

Players 
- id 
- name 

Games 
- id 
- game_type_id 
- season_id 


Goals 
- player_id 
- game_id 

Assists 
- player_id 
- game_id 

我一直努力試圖建立一個查詢/視圖,這將使我的球員的目標,並協助計數每個賽季和遊戲類型。每個球員都列出了每個賽季和遊戲類型,無論他們是否有進球/助攻,這一點很重要。

該查詢將用於創建視圖。它可以在一個查詢中完成嗎?

更新:這是一個SQL Fiddle與一些生產樣品數據。

+0

也似乎缺少一個表中有沒有'GameType' – swasheck

+0

的'GameType'表其實並不重要,因爲我需要的是在「遊戲」表中找到的遊戲類型的ID。 我會盡量在SQL小提琴中弄點東西。 –

+0

另外,「目標」和「助攻」都有一個缺失值(比如該球員在該遊戲中的總進球數),或者如果球員有多個目標,您是否有多個「player_id」和「game_id」在一場比賽中? – swasheck

回答

3

修訂

SELECT 
    players.id, 
    players.name, 
    games.season_id, 
    games.game_type_id, 
    sum(CASE WHEN g.goals IS NULL THEN 0 ELSE g.goals END) AS goals, 
    sum(CASE WHEN a.assists IS NULL THEN 0 ELSE a.assists END) AS assists 
FROM players 
CROSS JOIN games 
LEFT JOIN (
    SELECT 
    game_id, player_id, 
    count(*) AS goals 
    FROM goals 
    GROUP BY 
    game_id, player_id 
) g ON 
    g.player_id = players.id 
    AND g.game_id = games.id 
LEFT JOIN (
    SELECT 
    game_id, player_id, 
    count(*) AS assists 
    FROM assists 
    GROUP BY 
    game_id, player_id 
) a ON 
    a.player_id = players.id 
    AND a.game_id = games.id 
GROUP BY 
    players.id, 
    players.name, 
    games.season_id, 
    games.game_type_id 

這不是很短的版本,但它應該是現在。

+0

我在查看數據時發現了一些不一致的情況。這是一個[示例數據集](http://sqlfiddle.com/#!2/8312c/6)。你會發現從第一個查詢和你的目標數不匹配。 –

+0

@YanSarazin你是對的,這是我的錯!它的根在第二個左連接 - 它克隆行。我認爲第一個答案沒有這個錯誤。 – pkuderov

+0

您的更新似乎是贏家! –

3
SELECT 
    players.id, 
    players.name, 
    games.season_id, 
    games.game_type_id, 
    SUM(COALESCE(assists.rows, 0))    AS assists, 
    SUM(COALESCE(goals.rows, 0))    AS goals 
FROM 
    players 
CROSS JOIN 
    games 
LEFT JOIN 
    (SELECT game_id, player_id, COUNT(*) AS rows FROM assists GROUP BY game_id, player_id) AS assists 
    ON assists.game_id = games.game_id 
LEFT JOIN 
    (SELECT game_id, player_id, COUNT(*) AS rows FROM goals GROUP BY game_id, player_id) AS assists 
    ON goals.game_id = games.game_id 
GROUP BY 
    players.id, 
    players.name, 
    games.season_id, 
    games.game_type_id 

但它可能會提高性能,如果你有一個Seasons表和GameType表。

SELECT 
    players.id, 
    players.name, 
    seasons.id, 
    game_types.id, 
    SUM(COALESCE(assists.rows, 0))    AS assists, 
    SUM(COALESCE(goals.rows, 0))    AS goals 
FROM 
    players 
CROSS JOIN 
    seasons 
CROSS JOIN 
    game_types 
LEFT JOIN 
    games 
    ON games.season_id = seasons.id 
    AND games.game_type = game_types.id 
LEFT JOIN 
    (SELECT game_id, player_id, COUNT(*) AS rows FROM assists GROUP BY game_id, player_id) AS assists 
    ON assists.game_id = games.game_id 
LEFT JOIN 
    (SELECT game_id, player_id, COUNT(*) AS rows FROM goals GROUP BY game_id, player_id) AS assists 
    ON goals.game_id = games.game_id 
GROUP BY 
    players.id, 
    players.name, 
    seasons.id, 
    game_types.id 
+1

b!打敗了我。左邊的連接是不是也需要在'player_id'上? – swasheck

+0

不得不修復一些拼寫錯誤以獲得此查詢運行,但計數都是關閉的。我用SQL小提琴更新了我的問題。 –

0

真棒,我沒想到十字架的加盟,我想出了:

從玩家選擇 players.id,games.game_type_id,games.season_id,GC,AC

左加入(select count(id)as c,player_id,game_id from players group by player_id,game_id)作爲g.player_id = players.id上的g。

left join(select count(id)as c,player_id,game_id from由player_id,game_id組成的助攻組)作爲a.player_id = players.id

right加入遊戲games.id = g.game_id和games.id = a.game_id group by players.id,games.game_type_id,games.season_id;

1

試試這個:

select p.id, 
    p.name, 
    gm.season_id, 
    gm.game_type_id, 
    sum(gl.goalcount), 
    sum(a.AssistCount) 
from players p 
left join 
(
    select game_id, player_id, count(*) GoalCount 
    from goals 
    group by game_id, player_id 
) gl 
    on p.id = gl.player_id 
left join 
(
    select game_id, player_id, count(*) AssistCount 
    from assists 
    group by game_id, player_id 
) a 
    on p.id = a.player_id 
left join games gm 
    on gl.game_id = gm.id 
    and a.game_id = gm.id 
where season_id is not null 
group by p.id, 
    p.name, 
    gm.season_id, 
    gm.game_type_id 

看到SQL Fiddle with Demo