2015-04-29 67 views
2

我有兩個表:玩家名稱匹配如何計算同一個表中的兩個單獨的列並將它們總計爲一個新列

SELECT * FROM playernames; 
id |  name  
----+------------------ 
38 | Abe Lincoln 
39 | Richard Nixon 
40 | Ronald Reagan 
(3 rows) 

SELECT * FROM matches; 
match_id | winner | loser 
----------+--------+------- 
     6 |  38 | 39 
     8 |  38 | 39 
     9 |  39 | 38 
     10 |  38 | 39 
     11 |  40 | 39 
(5 rows) 

我需要創建一個返回四列的單一查詢:ID,姓名,贏了,比賽。但即使使用連接和子查詢,我似乎也無法在一個查詢中完成所有操作。我最接近的是執行兩個單獨的查詢。這是計算每個玩家贏得總查詢:

SELECT playernames.id, name, COUNT(*) AS wins 
FROM matches, playernames 
WHERE winner = playernames.id 
GROUP BY playernames.id, winner; 
id |  name  | wins 
----+------------------+------ 
38 | Abe Lincoln  | 3 
39 | Richard Nixon | 1 
40 | Ronald Reagan | 1 
(3 rows) 

但我必須發出一個單獨的查詢,如果我要正確地計算比賽的每個球員總數:

SELECT playernames.id, name, COUNT(*) 
FROM matches, playernames 
WHERE playernames.id = winner 
OR playernames.id = loser 
GROUP BY playernames.id; 
id |  name  | count 
----+------------------+------- 
40 | Ronald Reagan |  1 
38 | Abe Lincoln  |  4 
39 | Richard Nixon |  5 
(3 rows) 

我避免把這些問題與我在將這些問題結合到單個查詢中所做的許多不正確嘗試混淆起來。任何人都可以告訴我如何正確地將這兩個查詢合併爲一個?

+0

只是一個評論,爲什麼不重新命名錶playernames到只是球員? – jarlh

+0

請看下面,postgresql沒有NVL功能。 –

回答

4

我會使用一個連接來獲得一個球員參加了所有比賽,再算上一個case表達式只提取他贏得的那些:

SELECT playernames.id, name, 
      COUNT(CASE playernames.id WHEN winner THEN 1 ELSE NULL END) AS wins, 
      COUNT(match_id) AS matches 
FROM  playernames 
LEFT JOIN matches ON playernames.id IN (winner, loser) 
GROUP BY playernames.id, name; 
+0

果然,這是做到了。謝謝。有趣的是,您的解決方案包含我正在採用的課程中未涵蓋的元素。但是我不能和講師或助教協商,因爲他們的論壇不在線,直到另行通知。現在我懷疑這可能是通過課堂中教授的簡單JOIN和子查詢解決的。我無法從postgresql文檔中找到它。 –

+1

這是錯誤的,因爲你沒有得到沒有任何匹配的球員... –

+0

事實上,我只是添加了一個球員與0比賽,你是對的,他沒有出現在輸出。我不知道這是否與Mureinik提出的查詢或我的模式有關。具有0個匹配的玩家在匹配表中沒有任何行,只有玩家名稱表中的一行。 –

相關問題