如何计算同一个表中的两个单独的列并将它们相加到一个新列中

时间:2015-04-29 07:04:28

标签: sql postgresql join count subquery

我有两张桌子:播放器名称匹配

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,name,wins,matches 。但即使使用了连接和子查询,我似乎无法在一个查询中获得所有这些内容。我最接近的是执行两个单独的查询。这是计算每位玩家总胜利的查询:

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)

我通过将这些问题合并到单个查询中的许多错误尝试,避免使这个问题变得混乱。谁能告诉我如何将这两个查询正确地合并为一个?

1 个答案:

答案 0 :(得分: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;