完全禁止使用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.winner
和matches.loser
列中,我不确定如何在standings
视图中聚合它们。
另外,你会说matches
表是规范化的吗?
非常感谢任何帮助。
编辑:更改了matches
内容。
答案 0 :(得分:0)
对于简单的情况,你展示的只有一些你应该修复的东西。再次针对您展示的问题。
首先:更改表matches
的列类型,它不应该是SERIAL
,因为它是自动增量类型列(不是真实类型)。这两列都是foreign keys
,应该是integer
,int
或bigint
作为
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;