【发布时间】:2020-05-08 19:42:02
【问题描述】:
关于 PostgreSQL 的这个问题困扰了我很长一段时间。 我尝试了自己并搜索了所有可能的地方,但最终无法得出将第 3 组的玩家考虑在内的结果。 所以即使这个问题可能是重复的,也没有找到正确的答案。 希望得到一些帮助。
问题如下: 编写一个 SQL 查询,返回一个包含每个组中获胜者的表。 每条记录都应包含该组的ID和该组中获胜者的ID(同组的玩家竞争)。 记录应该按照组的ID号增加排序,如果平局,ID最小的玩家获胜。
鉴于此架构:
玩家:
+-------------+-------+
| Column Name | Type |
+-------------+-------+
| player_id | int |
| group_id | int |
+-------------+-------+
匹配:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| match_id | int |
| first_player | int |
| second_player | int |
| first_score | int |
| second_score | int |
+---------------+---------+
以下示例:
球员表:
+-----------+------------+
| player_id | group_id |
+-----------+------------+
| 20 | 2 |
| 30 | 1 |
| 40 | 3 |
| 45 | 1 |
| 50 | 2 |
| 40 | 1 |
+-----------+------------+
匹配表:
+------------+--------------+---------------+-------------+--------------+
| match_id | first_player | second_player | first_score | second_score |
+------------+--------------+---------------+-------------+--------------+
| 1 | 30 | 45 | 10 | 12 |
| 2 | 20 | 50 | 5 | 5 |
| 3 | 65 | 45 | 10 | 10 |
| 4 | 30 | 65 | 3 | 15 |
| 5 | 45 | 65 | 8 | 4 |
+------------+--------------+---------------+-------------+--------------+
您的查询应该返回:
+-----------+------------+------------+
| group_id | winner_id | tot_score |
+-----------+------------+------------+
| 1 | 45 | 30 |
| 2 | 20 | 5 |
| 3 | 40 | 0 |
+-----------+------------+------------+
在第 1 组中,45 名球员得分最高。 在第 2 组中,两名球员都得了 5 分,但球员 20 的 ID 较低,因此他是获胜者。 第三组只有一名球员,虽然他没有参加任何比赛,但他是胜利者。
到目前为止,我做到的最好的事情是(在 PostgreSQL 上):
SELECT group_id, player_id, score
FROM
(
SELECT sq2.player_id, p.group_id, sq2.score,
RANK() OVER (PARTITION BY p.group_id ORDER BY score DESC) as position
FROM
(
SELECT player_id, SUM(score) score
FROM (
SELECT first_player as player_id, first_score as score FROM matches
UNION ALL
SELECT second_player as player_id, second_score as score FROM matches
) as sq1
GROUP BY player_id
) as sq2
right join players p
on p.player_id = sq2.player_id
) as sq3
WHERE position = 1 order by group_id, player_id
输出如下:
+-----------+-----------------------+------------+
| group_id | player_id | score |
+-----------+-----------------------+------------+
| 1 | 45 | 30 |
| 2 | 20 | 5 |
| 2 | 50 | 5 |
| 3 | [NULL](instead of 40) | [NULL] (should be 0)|
+-----------+-----------------------+------------+
您能否帮助生成具有完整正确结果的查询? (包含第 3 组玩家的详细信息)
还想知道为什么查询在 player_id 中为正确的连接返回 NULL。 感谢您的帮助!
* 这个问题显然也是 Leetcode.com 上的一个问题,叫做“Tournament Winners” *
【问题讨论】:
-
如果出现平局,即一个小组有两个不同的玩家得分相同,那么预期的结果是什么?
-
也许这回答了你的问题? stackoverflow.com/questions/51487670/…
-
@jarlh 最低 ID 获胜
-
这是一个小提琴,所以所有帮助者都很容易帮助:dbfiddle.uk/…
-
@JaimeS 谢谢,但此解决方案将玩家排除在第 3 组之外
标签: sql postgresql subquery left-join greatest-n-per-group