2017-01-22 75 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()'。 –