3

我有以下表格:

Players
- id
- name

Games
- id
- game_type_id
- season_id


Goals
- player_id
- game_id

Assists
- player_id
- game_id

我一直在努力尝试构建一个查询/视图,该查询/视图将为我提供每个赛季和游戏类型的球员目标和助攻数。对于每个球员来说,重要的是要针对每个赛季和比赛类型列出,无论他们是否有进球/助攻。

该查询将用于创建视图。可以在一个查询中完成吗?

更新:这是一个带有一些生产示例数据的SQL Fiddle 。

4

4 回答 4

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
于 2012-09-14T16:37:35.173 回答
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

这不是很短的版本,但现在应该是。

于 2012-09-14T16:57:32.933 回答
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

于 2012-09-14T19:51:50.990 回答
0

太棒了,我没有想到交叉连接,我想出了:

从玩家中选择 player.id、games.game_type_id、games.season_id、gc、ac

left join (select count(id) as c, player_id, game_id from goal group by player_id, game_id) as g on g.player_id = player.id

left join (select count(id) as c, player_id, game_id from assistants group by player_id, game_id) as a on a.player_id = player.id

右加入games.id = g.game_id和games.id = a.game_id上​​的游戏按players.id、games.game_type_id、games.season_id分组;

于 2012-09-14T18:07:57.670 回答