我是SQL新手并尝试从在线教程中学习基础知识。我坚持查询,并希望得到一些建议。
目前,目标是使用查询为锦标赛创建一个球员站立桌。我有两张桌子;球员和比赛。
tournament=> select * from players;
id | name
----+------------------
19 | Melpomene Murray
20 | Randy Schwartz
46 | Ricardo
(3 rows)
tournament=> select * from matches;
winner_id | loser_id
-----------+----------
19 | 20
(1 row)
我需要汇总胜利和匹配才能做到这一点:
id | name | wins | p_matches
----+------------------+------+-----------
19 | Melpomene Murray | 1 | 1
20 | Randy Schwartz | 0 | 1
46 | Ricardo | 0 | 0
现在这是我最好的猜测:
tournament=> select players.id, players.name, subq.wins, subq2.p_matches from players,
(select players.id,count(players.id) as wins from players,matches
where matches.winner_id = players.id group by players.id) as subq,
(select count(*) as p_matches from matches) as subq2;
id | name | wins | p_matches
----+------------------+------+-----------
19 | Melpomene Murray | 1 | 1
20 | Randy Schwartz | 1 | 1
46 | Ricardo | 1 | 1
很大一部分问题源于我的子查询。当我单独运行它时,由于条件限制,我得到一行。我想列出所有ID,其中没有赢的行保持为零。
tournament=> select players.id,count(players.id) as wins from players,matches
where matches.winner_id = players.id group by players.id;
id | wins
----+------
19 | 1
我听说coalesce可以做这样的事情,但我还没能把它变成工作。想法?
答案 0 :(得分:1)
还有这个,我不确定哪个表现更好(可能比多个子查询更好)。
select p.id,
p.name,
count(case when m.winner_id = p.id then 1 end) won,
count(m.*) total
from players p
left join matches m
on m.winner_id = p.id
or p.id = m.loser_id
group by p.id, p.name;
这将选择所有玩家记录,并且左边连接匹配表(无论玩家ID是否存在),然后对结果进行分组,在这种情况下,可以使用聚合函数,如count。
第一个计数聚合函数只计算获胜者列中获得玩家ID的行(赢),如果他们在任一列中,第二个将计算它们。
答案 1 :(得分:0)
可能是这个?:
t=# with a as (
select p.*, w.w wins, coalesce(w.w, l.l) p_m
from players p
left outer join matches w on w.w = p.id
left outer join matches l on l.l = p.id
)
select id,name, count(wins), count(p_m)
from a
group by id, name
order by id;
id | name | count | count
----+-------------------+-------+-------
19 | Melpomene Murray | 1 | 1
20 | Randy Schwartz | 0 | 1
46 | Ricardo | 0 | 0
(3 rows)
答案 2 :(得分:0)
一种简单的方法是在select子句中使用子查询:
select
id,
name,
(select count(*) from matches m where p.id = m.winner_id) as wins,
(select count(*) from matches m where p.id in (m.winner_id, m.loser_id)) as p_matches
from players p
order by id;