我有两张桌子:播放器名称和匹配。
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)
我通过将这些问题合并到单个查询中的许多错误尝试,避免使这个问题变得混乱。谁能告诉我如何将这两个查询正确地合并为一个?
答案 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;