SQL 3方式排名结合逻辑

时间:2018-02-23 15:15:07

标签: sql postgresql

我正在使用postgresql编写一个程序,以显示在5个循环池中玩的视频游戏锦标赛的排名。所以有可能在某个地方有3条领带。我找到了确定头对头获胜者的逻辑:Here这对超级有帮助,但它不适用于3路并列。我稍微修改了架构,所以这就是我使用的:

[poolteam]
-team 
-wins
 [versus]
 -team1
 -team2
 -win 

对阵表只是告诉我们谁赢得了两队之间的比赛。然后我通过将其传递到新表中来获得团队的排名

select team, wins, RANK() OVER (ORDER BY wins desc) AS rank 
    INTO rankTable 
from poolteam;

然后使用链接的答案,我可以得到排名和头对头的领带断路器。我写这篇文章是为了找出是否有超过2支具有相同等级的球队

select rank 
from finalStandings 
group BY rank having count(*) >2

逻辑首先看到大多数胜利,然后是头对头,然后如果超过2个并列的球队与所有球队并列领先,这是一个例子:

Team A 3-1
Team B 2-2
Team C 2-2
Team D 2-2
Team E 1-3

A队击败B,C,E,B队击败C& D,C队击败E& D,D队击败E& A队,E队击败B队。

在这种情况下,三支并列球队(B,C,D)有2胜,但由于B击败两支并列球队,他们将获得第二名,C将获得第三名,因为他们赢得了头部胜利D.

在所有三支球队相互击败的情况下,决胜局会看到赢得比赛的比赛很容易计算,这只是我需要帮助的一个场景。

1 个答案:

答案 0 :(得分:0)

对于三支相同级别的队伍,即A B和C,两者之一:

  1. 一支队伍(例如A)击败了B和C,一支队伍(例如B)击败了一支 (C),一支球队(C)没有击败任何一支球队,或者
  2. 所有球队都完全击败了另一支球队,并且有一个循环(例如,B拍,B拍C和C拍A)。

您会看到这是因为,如果三支队伍具有相同的排名并且互相打过一次,那么就打了三场比赛,必须给出三场胜利,但是没有一支队伍能打两场以上,所以赔率为1、1 1或2、1、0。这意味着使用获胜表和具有排名的球队表,您可以通过简单地计算排名靠前的胜利并按其排名来获得想要的结果。

假设您具有以下架构: 名为teamrank的表名称和名称,获胜和损失列,以及具有获胜者和输者列的匹配表,您可以使用:

模式:

CREATE TABLE matches (winner CHAR(1), loser CHAR(1));
insert into matches (winner, loser) values('A','B');
insert into matches (winner, loser) values('A','C');
insert into matches (winner, loser) values('D','A');
insert into matches (winner, loser) values('A','E');
insert into matches (winner, loser) values('B','C');
insert into matches (winner, loser) values('B','D');
insert into matches (winner, loser) values('E','B');
insert into matches (winner, loser) values('C','D');
insert into matches (winner, loser) values('C','E');
insert into matches (winner, loser) values('D','E');
create table team (name CHAR(1));
insert into team (name)  VALUEs('A');
insert into team (name)  VALUEs('B');
insert into team (name)  VALUEs('C');
insert into team (name)  VALUEs('D');
insert into team (name)  VALUEs('E');
CREATE TABLE TEAMSTAT (NAME CHAR(1), WINS SMALLINT, LOSSES SMALLINT);
insert into teamstat SELECT T.NAME,
       coalesce(m1.wins,0) as wins,
       coalesce(m2.losses,0) as losses
from team t
LEFT JOIN(select winner, count(winner) as wins 
          from matches
          group by winner
         ) m1 ON m1.winner = t.name 
LEFT JOIN(select loser, count(loser) as losses
          from matches
          group by loser
         ) m2 ON m2.loser = t.name

查询:

select t.name, t.wins, t.losses
, sum(case when t.name = m.winner and t.wins = t2.wins then 1 else 0 end) as wins_in_rank
, sum(case when t.name = m.winner and t.wins <= t2.wins then 1 else 0 end) as wins_in_or_above_rank
from teamstat t
 left join teamstat t2 on t2.name <> t.name and t.wins <= t2.wins
 left join matches m on m.winner in (t2.name, t.name) and m.loser in(t2.name, t.name)
group by t.name, t.wins, t.losses
order by t.wins desc, "wins_in_rank" desc, "wins_in_or_above_rank" desc

更新的小提琴:http://sqlfiddle.com/#!17/585c8d/13/0