我有一个播放器表,我正在尝试构建一个SQL查询来配置它们以分配特定轮次的匹配.每个玩家都有一个分数,我想配对有相似分数的玩家.我不希望任何玩家出现在一对以上.
首先,我创建了以下视图:
CREATE VIEW all_possible_pairs AS
SELECT p1.id AS player1, p2.id AS player2
FROM players as p1, players as p2
WHERE p1.id < p2.id
ORDER BY ABS(p1.score - p2.score)
Run Code Online (Sandbox Code Playgroud)
all_possible_pairs获得所有可能的玩家对,并避免匹配玩家自己并包括相同的两次(例如a,bb,a).数据以我想要的方式排序,使得首先出现的对优先于稍后出现的对(因为它们具有更接近的分数).
我想从all_possible_pairs中选择玩家第一次出现的行.在结果表中,每个玩家应该在两列中仅出现一次(例如,如果玩家首次出现在player2中,则他们不应该出现在任何后续行中的player1或player2中).
所以,例如,假设我们有玩家a,b,c,d和all_possible_players看起来像这样:
player1, player2
a b
a c
a d
b c
b d
c d
Run Code Online (Sandbox Code Playgroud)
我想从这个视图中选择,以便我得到以下内容:
player1, player2
a b
c d
Run Code Online (Sandbox Code Playgroud)
我一直在撞墙一段时间尝试各种SELECT DISTINCT条款,但我似乎无法做到正确.例如,上例中的player1上的SELECT DISTINCT将包含b,c,这不是我想要的,因为它意味着b和c在表中两次.
不要列出所有可能的配对,而是创建一个为每个玩家提供排名而不是分数的视图:
CREATE VIEW ranked_players AS
SELECT id AS Playerid, row_number() OVER (order by score) as PlayerRank
FROM players
Run Code Online (Sandbox Code Playgroud)
现在,当你将它们配对时,将奇数排名的邻居与相邻的偶数排名的邻居配对:
SELECT ranked1.PlayerId player1,
ranked2.PlayerId player2
FROM ranked_players AS
ranked1
INNER JOIN ranked_players
AS ranked2 ON ranked1.
PlayerRank+ 1 = ranked2.
PlayerRank
WHERE ranked1.playerrank % 2
= 1
Run Code Online (Sandbox Code Playgroud)
看看是否能满足您的需求。