Postgresql:过滤重复对

时间:2016-01-11 09:24:02

标签: postgresql

我是从移动设备上问这个,所以对格式错误道歉。对于下表。

表格球员

| ID | name |matches_won|
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
| 1  | bob  | 3         |
| 2  | Paul | 2         |
| 3  | John | 4         |
| 4  | Jim  | 1         |
| 5  | hal  | 0         |
| 6  | fin  | 0         |

我想在查询中将两个玩家配对。谁拥有类似或接近相似的比赛数量。因此查询应显示以下结果。

| ID | NAME | ID | NAME |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
| 3  | John |  1 | bob  |
| 2  | paul |  4 | Jim  |
| 5  | hal  |  6 | fin  |

到目前为止,我已尝试过此查询。但它给出了重复对。

Select player1.ID,player1.name,player2.ID,player2.name
From player as player1,
          player as player2
Where 
player1.matches_won >= player2.matches_won
And player1.ID  ! = player2.ID;

该查询会将玩家与其他玩家中的所有玩家匹配得最多。虽然我只希望一个玩家在结果中只出现一次。与最接近他的胜利的球员。

我尝试过子查询。但我不知道如何去做,因为它只返回一个结果。聚合也不在where子句中工作。所以我不知道如何实现这一目标。

2 个答案:

答案 0 :(得分:0)

恕我直言,实现这一目标的一种更简单的方法是按照胜利次数命令玩家,将这些等级除以2以创建比赛和自我加入。 CTE(with表达式)允许您相对优雅地执行此操作:

WITH wins AS (
    SELECT id, name, ROW_NUMNBER() OVER (ORDER BY matches_won DESC) AS rn   
    FROM players
)
SELECT     w1.id, w1.name, w2.id, w2.name
FROM       (SELECT id, name, rn / 2 AS rn
            FROM   wins
            WHERE  rn % 2 = 1) w1
LEFT JOIN (SELECT id, name, (rn - 1) / 2 AS rn
           FROM   wins
           WHERE  rn % 2 = 0) w2 ON w1.rn = w2.rn

答案 1 :(得分:0)

按表格的赢比赛按降序添加行号,并将奇数行号与相邻的偶数行连接起来:

with players as (
    select *, row_number() over (order by matches_won desc) rn
    from player)

select a.id, a.name, b.id, b.name
from players a
join players b
on a.rn = b.rn- 1
where a.rn % 2 = 1

 id | name | id | name 
----+------+----+------
  3 | John |  1 | bob
  2 | Paul |  4 | Jim
  5 | hal  |  6 | fin
(3 rows)