带有自定义关系的sql排名

时间:2019-02-25 13:06:34

标签: php mysql sql

您好,您可以帮我通过自定义联系获得排名吗? 我有一个分数表,用于存储评委给出的所有分数。

+----+----------+-------------+--------+
| Id | judge_id |performer_id | score  |
+----+----------+-------------+--------+
| 1  |    1     |      1      |    98  |
| 2  |    1     |      2      |    98  |
| 3  |    1     |      3      |    94  |
| 4  |    1     |      4      |    96  |
| 5  |    2     |      1      |    93  |
| 6  |    2     |      2      |    80  |
+----+----------+-------------+--------+

这是我搜索的代码。

SELECT
   id
 , judge_id
 , performer_id
 , score
 , FIND_IN_SET(
       score
     , (SELECT
          GROUP_CONCAT(DISTINCT score ORDER BY score DESC) 
        FROM
          scores
        WHERE
          judge_id = 1
        )
   ) AS rank 
 FROM
   scores
 WHERE
   judge_id = 1
 ORDER BY rank ASC

的输出是:

+----+----------+-------------+--------+------+
| Id | judge_id |performer_id | score  | rank |
+----+----------+-------------+--------+------+
| 1  |    1     |      1      |    98  |  1   |
| 2  |    1     |      2      |    98  |  1   | 
| 3  |    1     |      4      |    96  |  3   |
| 4  |    1     |      3      |    94  |  4   |
+----+----------+-------------+--------+------+

它正在工作,但是输出不是我想要的。 我想获得这样的排名和联系。

+----+----------+-------------+--------+------+
| Id | judge_id |performer_id | score  | rank |
+----+----------+-------------+--------+------+
| 1  |    1     |      1      |    98  |  1.5 |
| 2  |    1     |      2      |    98  |  1.5 | 
| 3  |    1     |      4      |    96  |  3   |
| 4  |    1     |      3      |    94  |  4   |
+----+----------+-------------+--------+------+

在哪里获得领带的所有等级,然后除以该等级中有多少表演者的领带。

例如

performer 1  score 98 rank 1
performer 2  score 98 rank 1

假设表演者2的排名应为2

我想像

那样计算

1 + 2 = 3然后将其除以2,因为2位表演者并列第1名

1 = 2 = 3/2

答案是1.5

对不起我的英语

但请问有人可以帮助我吗?我陷入了这个问题。

1 个答案:

答案 0 :(得分:1)

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(performer_id SERIAL PRIMARY KEY
,score  INT NOT NULL
);

INSERT INTO my_table VALUES
(1,98),
(2,98),
(3,94),
(4,96);

SELECT x.*
     , y.rank
  FROM my_table x
  JOIN 
     ( SELECT score
            , SUM(i)/COUNT(*) rank
         FROM 
            ( SELECT score
                   , @i:=@i+1 i
                FROM my_table x
               ORDER 
                  BY score DESC
                   , performer_id
            ) a
         JOIN
            ( SELECT @i:=0 ) vars
        GROUP 
           BY score
     ) y
    ON y.score = x.score;

+--------------+-------+--------+
| performer_id | score | rank   |
+--------------+-------+--------+
|            1 |    98 | 1.5000 |
|            2 |    98 | 1.5000 |
|            3 |    94 | 4.0000 |
|            4 |    96 | 3.0000 |
+--------------+-------+--------+

注意:对于较新版本的MySQL,您将使用Windowing函数/ CTE(我不太确定正确的术语)。我已经为较旧的版本编写了此代码,尽管MySQL在以这种方式初始化变量时可能会遇到问题。如果存在问题,这是初始化变量的另一种方法(有点“ hacker”-理论上不正确,但实际上还不错)...

SELECT x.*
     , y.rank
  FROM my_table x
  JOIN 
     ( SELECT score
            , SUM(i)/COUNT(*) rank
         FROM 
            ( SELECT score
                   , @j:=@j+1 i
                FROM my_table x
                JOIN ( SELECT @j:=0 ) vars
               ORDER 
                  BY score DESC
                  , performer_id
            ) a

        GROUP 
           BY score
     ) y
    ON y.score = x.score;

+--------------+-------+------+
| performer_id | score | rank |
+--------------+-------+------+
|            1 |    98 |  1.5 |
|            2 |    98 |  1.5 |
|            3 |    94 |    4 |
|            4 |    96 |    3 |
+--------------+-------+------+