2015-04-29 64 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个匹配的玩家在匹配表中没有任何行,只有玩家名称表中的一行。 –

相关问题