我想弄清楚如何正确显示排名,如果多个作者的文章数量相同,那么他们会获得相同的排名,然后排名会在正确的位置恢复。例如,如果前 4 人的文章数相同,那么我希望他们都排名为 1,然后第 5 个人排名为 5。以下查询输出如下所示:
SELECT @rownum:=@rownum + 1 as Rank,
subq1.*
FROM ( SELECT Uni.University_Name, COUNT( * ) AS ArticleCount
FROM Author_University AS AU, University AS Uni, Articles AS Art
WHERE Art.Year_Published >= '2010'
AND Uni.University_ID = AU.University_ID
AND Art.Article_ID = AU.Article_ID
GROUP BY University_Name
ORDER BY ArticleCount DESC
LIMIT 0 , 25
) subq1,
(SELECT @rownum := 0) r
这是使用变量实现同等排名的一种方法:
该方法中三个变量的作用是:
@rank
– 计算和存储连续的、唯一的排名;@lastrank
– 存储上一行的排名;@lastcount
– 存储上一行的计数值。这是
Rank
表达式的工作原理。如果当前行ArticleCount
等于@lastcount
,则ArticleCount = @lastcount
条件的计算结果为true
,而另一行的计算ArticleCount <> @lastcount
结果当然为false
。在算术运算 (*
) 的上下文中,true
隐式转换为 1 和false
0。因此,表达式等效于:反过来,它简化为 just
@lastrank
。因此,当ArticleCount
等于 时@lastcount
,@lastrank
保留其前一行的值。然后将当前计数存储在中@lastcount
,以便与下一行进行比较。这种方式
@lastrank
保持不变,直到ArticleCount
不再等于@lastcount
。在这一点上true
和false
- 以及 1 和 0 - 交换位置并且表达式变得等价于此:所以最后
@lastrank
得到 的评估结果(@rank := @rank + 1)
,这将只是一个新的排名。但是请注意,它(@rank := @rank + 1)
实际上对每一行进行评估,但@lastrank
仅在ArticleCount
更改为新值时才分配给它。正是
@rank
每一行都增加的事实使我们能够获得这种排名,但存在差距。为了比较,考虑这个 CASE 表达式:或使用 IF() 函数的等效函数:
这些变化中的每一个都会给我们同样的排名,但排名不会有差距——也就是说,
1, 1, 3, 4, 4, 4, 7
我们会得到,而不是 eg1, 1, 2, 3, 3, 3, 4
。原因是,(@rank := @rank + 1)
每种情况下的赋值只有当/当Article
不同于@lastcount
- 换句话说,只有在发生变化时@rank
才会增加并分配给,这与第一种方法不同,后者不断增加。@lastrank
ArticleCount
@rank