【问题标题】:How to count two separate columns in the same table and sum them into a new column如何计算同一个表中的两个单独的列并将它们相加成一个新列
【发布时间】:2015-07-08 07:32:21
【问题描述】:

我有两张表:playersnamesma​​tches

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)

我正在避免将这个问题与我在将这些组合成一个查询时所做的许多错误尝试搞混。谁能告诉我如何正确地将这两个查询合并为一个?

【问题讨论】:

  • 只是一个评论,为什么不将表玩家名重命名为只是玩家?
  • 见下文,postgresql没有NVL功能。

标签: sql postgresql join count subquery


【解决方案1】:

我会使用一次连接来获取玩家参加的所有比赛,然后计算 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;

【讨论】:

  • 果然做到了。谢谢。有趣的是,您的解决方案包含我正在学习的课程中未涵盖的元素。但我无法与导师或助教进行协商,因为他们的论坛处于离线状态,直至另行通知。现在我怀疑这是否可以通过课堂上教授的简单 JOIN 和子查询来解决。而且我无法从 postgresql 文档中弄清楚。
  • 实际上我只是添加了一个 0 匹配的玩家,你是对的,他没有出现在输出中。我不知道这是否是 Mureinik 提出的查询或我的模式的问题。一个有 0 场比赛的球员在 matchs 表中没有任何行,在 playernames 表中只有一行。
  • @LukeSheppard 确实,查询没有处理没有匹配的玩家。像 Pavel 建议的那样,使用 left join 来处理它们。
  • 是的。 LEFT JOIN 做到了。再次感谢。
猜你喜欢
  • 2019-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-23
  • 1970-01-01
  • 2020-06-14
  • 2016-04-10
  • 2020-06-09
相关资源
最近更新 更多