SQL:从结果页面计算团队的游戏数量

时间:2015-02-18 14:38:12

标签: sql postgresql

完全禁止使用SQL 我创建了下表,它存储了两个对手之间的匹配数据以及获胜者得到的分数。

CREATE TABLE matches ( winner INT references players,
                       loser INT references players,
                       gamepoints INT);

我创建了以下VIEW来显示积分榜:

CREATE VIEW standings as 
  select 
    players.id, 
    players.name, 
    count(matches.winner) as number_of_wins, 
    coalesce(sum(matches.gamepoints),0) as points
  from players left join matches 
  on players.id = matches.winner
  group by players.name, players.id
  order by number_of_wins desc, points desc;

我希望添加一个列,显示玩家玩过多少游戏。我的问题是游戏同时出现在matches.winnermatches.loser列中,我不确定如何在standings视图中聚合它们。

另外,你会说matches表是规范化的吗?

非常感谢任何帮助。

编辑:更改了matches内容。

2 个答案:

答案 0 :(得分:0)

对于简单的情况,你展示的只有一些你应该修复的东西。再次针对您展示的问题。

首先:更改表matches的列类型,它不应该是SERIAL,因为它是自动增量类型列(不是真实类型)。这两列都是foreign keys,应该是integerintbigint

作为

create table matches (
    winner bigint,
    loser bigint,
    gamepoints int,
    constraint fk_player_winner foreign key (winner) 
          references players(id),
    constraint fk_player_loser foreign key (loser) 
          references players(id)
);

第二:要知道玩家用点数创造了多少游戏,你可以创建两个子查询,一个与获胜者,一个与失败者一起加入两个总和值。问题在于你必须从两者中减少游戏点:

select w.id, w.name, w.gp-l.gp as gamepoints, w.ng+l.ng
  from (select p.id, p.name, sum(m.gamepoints) gp, count(m.winner) as ng
          from players p inner join matches m 
                             on p.id=m.winner
         group by p.id, p.name ) w
        INNER JOIN
       (select p.id, p.name, sum(m.gamepoints) gp, count(m.loser) as ng
          from players p inner join matches m 
                             on p.id=m.loser
         group by p.id, p.name) l on w.id=l.id;

从中创建您的视图。

注意:也许我对这两个子查询有点过分了。可以通过两个players表和matches

之间的联接来解决问题

了解它如何在小提琴上发表:http://sqlfiddle.com/#!15/5b6a4/4

答案 1 :(得分:0)

在@Jorge Campos的帮助下,这就是解决方案:

CREATE VIEW games_won as 
    select p.id, p.name, coalesce(sum(m.gamepoints),0) gp, count(m.winner) ng
    from players p left join matches m
    on p.id=m.winner
    group by p.id, p.name;

CREATE VIEW games_lost as 
    select p.id, p.name, count(m.loser) as ng
    from players p left join matches m 
    on p.id=m.loser
    group by p.id, p.name;

CREATE VIEW standings as 
    select w.id, w.name, w.ng as wins, w.ng+l.ng as matches, w.gp as gamepoints 
      from games_won w INNER JOIN games_lost l 
      on w.id=l.id
      order by wins desc, gamepoints;
相关问题