2012-09-14 52 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