如何在mysql排名中获得正确的关系位置

时间:2014-05-30 18:10:18

标签: mysql ranking

这是我的代码,适用于关系,但不会跳过关系上的位置

SELECT   `item`, (`totalrate` / `nrrates`),
         @rank_count := @rank_count + (totalrate/nrrates < @prev_value) rank,
         @prev_value := totalrate/nrrates avg
FROM     table, (SELECT @prev_value := NULL, @rank_count := 1) init
 ORDER BY avg DESC

这是我得到的

item        (`totalrate` / `nrrates`)    rank     avg

Virginia        10.0000                    1      10
Ana             9.7500                     2      9.75
Angeie          9.72                       3      9.72
Carel           9.666666666                4      9.66
sammy           9.666666666                4      9.66
Oda             9.500000000                5      9.5

我想要

item        (`totalrate` / `nrrates`)    rank     avg

Virginia        10.0000                    1      10
Ana             9.7500                     2      9.75
Angeie          9.72                       3      9.72
Carel           9.666666666                4      9.66
sammy           9.666666666                4      9.66
Oda             9.500000000                6      9.5

跳过5位置

我想合并这个跳过关系的位置

(我从这篇文章中获取了以下代码 MySQL Rank in the Case of Ties

SELECT t1.name, (SELECT COUNT(*) FROM table_1 t2 WHERE t2.score > t1.score) +1
AS rnk
FROM table_1 t1

我如何修改我的代码以使其跳过上述代码的位置看起来很简单,但我还没有想到它。 感谢

2 个答案:

答案 0 :(得分:0)

在关系上,您可能希望跳过并将当前行数用作下一个不匹配的平均值行作为下一个等级。
以下应该可以帮到你

SELECT   `item`, @curr_avg := ( `totalrate` / `nrrates` )
       , case when @prev_avg = @curr_avg then @rank := @rank 
              else @rank := ( @cur_row + 1 )
          end as rank
       , @cur_row := ( @cur_row + 1 ) as cur_row 
       , @prev_value := @curr_avg avg
FROM     table
       , ( SELECT @prev_avg := 0, @curr_avg := 0
                , @rank := 0, @cur_row := 0 ) init
ORDER BY avg DESC

类似的例子

答案 1 :(得分:0)

这是另一种选择。首先,计算平均值。如果它们已经在表格中可用,那就更容易了(在小提琴演示中可以看到)。无论如何,等级是基于计算有多少项目的平均值低于当前项目的逻辑。

SELECT
A1.`item`,
A1.avg,
COUNT(A2.`item`) avg_rank
FROM
(
SELECT   `item`, (`totalrate` / `nrrates`),
         @prev_value := totalrate/nrrates avg
FROM     table, (SELECT @prev_value := NULL, @rank_count := 1) init
) A1   --alias for the inline view
INNER JOIN
(
SELECT   `item`, (`totalrate` / `nrrates`),
         @prev_value := totalrate/nrrates avg
FROM     table, (SELECT @prev_value := NULL, @rank_count := 1) init
) A2   --alias for the inline view
ON A2.avg < A1.avg
GROUP BY A1.id, A1.avg
ORDER BY A1.avg;

SQL Fiddle demo