0

我有一个User带有两个属性的简单表IDAGE 现在我想获得一个“排名”结果基于AGE

 User Table

ID      AGE
0        23
1        35
2        30
3        52
4        35
5        23
6        19

如果我这样做,select * from User order by AGE ASC我可以轻松获得如下排序结果:

ID      AGE
6        19
0        23
5        23
2        30
1        35
4        35
3        52

但我真正想要的是:

ID      RANK
6        0
0        1
5        1
2        3
1        4
4        4
3        6

我在下面提出了很好的解决方案,但它有一个微小的缺陷

SELECT U1.ID, count(*) AS RANK
FROM User U1, User U2
WHERE U1.age > U2.age
GROUP BY U1.ID ORDER BY RANK;

这给了我:

ID      RANK
0        1
5        1
2        3
1        4
4        4
3        6

这是正确的,只是我输掉了一个排名为零的原因WHERE U1.age > U2.age,因为对于最年轻的用户来说永远不会正确。

请高手指点一下这个问题,先谢谢了!

4

2 回答 2

2

不幸的是 MySQL 仍然缺乏对分析函数的支持。RANK()在 MySQL中模拟的一种方法

SELECT id, rank
  FROM
(
  SELECT id, @n := @n + 1, @r := IF(@a = age, @r, @n) rank, @a := age
    FROM user CROSS JOIN (SELECT @n := -1, @r := -1, @a := NULL) i
   ORDER BY age
) q

输出:

| 身份证 | 排名 |
|----|--------|
| 6 | 0 |
| 0 | 1 |
| 5 | 1 |
| 2 | 3 |
| 1 | 4 |
| 4 | 4 |
| 3 | 6 |

这是SQLFiddle演示


你应该在你的问题中告诉你,你实际上首先使用的是 Postgres。

不幸的是,@t-clausen.dk 删除了他的答案,鉴于您使用支持分析功能的 Postgres 的发现事实,这是绝对正确的

SELECT ID, RANK() OVER (ORDER BY age) - 1 rank
  FROM "user"

这是最好的方法。

这是SQLFiddle演示

于 2013-11-05T08:11:14.453 回答
1
SELECT t1.id, 
(SELECT COUNT(*) FROM User t2 WHERE t2.AGE < t1.AGE)
AS rnk
FROM User t1 order by rnk ;

样品小提琴

于 2013-11-05T08:07:05.140 回答