2017-01-22 79 views
2

首先,我想为模棱两可的标题道歉(我承诺一旦我真正意识到我正在尝试解决的问题,就修改它)!PostgreSQL - 在一列和两列中选择唯一值的计数

我有两个表,球员比赛,看起来像下面这样:

球员:

id name 
-- ---- 
1 John 
2 James 
3 April 
4 Jane 
5 Katherine 

匹配:

id winner loser 
-- ------ ----- 
1 1  2 
2 3  4 

记录在匹配表中赢家失败者表示两个播放器,其中由所述数据库中生成的ID柱,并且这些值之间的匹配列参考id列中的播放器表。

我想运行的吐出下面的查询:

player.id player.name total_wins total_matches 
--------- ----------- ---------- ------------- 
1   John  1   1 
2   James  0   1 
3   April  1   1 
4   Jane  0   1 
5   Katherine 0   0 

我现在有它检索total_wins查询,但我不知道如何让TOTAL_MATCHES最重要的是计数。

select p.id, p.name, count(m.winner) 
from player p left join match m on p.id = m.winner 
group by p.id, p.name; 

感谢您的帮助!

回答

4

尝试

select p.id, p.name, 
     sum(case when m.winner = p.id then 1 end) as total_wins, 
     count(m.id) as total_matches 
from player p 
left join match m on p.id in (m.winner, m.loser) 
group by p.id, p.name; 
+0

谢谢,这似乎返回正确的结果! 'p.id in(m.winner,m.loser)'相当于'p.id = m.winner AND p.id = m.loser'? – disposedtrolley

+0

此外,我只是修改case语句来读取'm.winner = p.id然后1 else 0 end'的情况,所以0将显示给没有胜利的玩家 - FYI给其他同样问题的玩家。 – disposedtrolley

+0

不,'p.id in(m.winner,m.loser)'与'p.id = m.winner或p.id = m.loser'相同,即'OR'不是'AND' – krokodilko

1

一种方法拆分match匹配表,所以你有一个单一的行赢得和损失。剩下的只是一个left join和聚集:

select p.id, p.name, coalesce(sum(win), 0) as win, count(m.id) as total_matches 
from player p left join 
    (select match, winner as id, 1 as win, 0 as loss from match 
     union all 
     select match, loser as id, 0 as win, 1 as loss from match 
    ) m 
    on p.id = m.id 
group by p.id, p.name; 
+0

谢谢!这个查询的工作原理,但我得到一个null值为玩家5胜,而不是0. – disposedtrolley

+0

@disposedtrolley。 。 。只需使用'coalesce()'。 –