MySql查询排名

参考:原文地址
翻译者原文地址

实际上没有秩函数MySQL,每当你需要查询从表聽排名基于一些功能/ MySQL的标准。但也有简单的查询,可以用来执行相同的。

在这里我描述查询执行的例子:

首先我们创建 players表,我们希望能获得红杉中排名。你会熟悉很多查询根据不同的需求。

参考文章的主要思路:
创建表

CREATE TABLE `players` (
  `pid` int(2) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `age` int(2) NOT NULL,
  PRIMARY KEY (`pid`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

INSERT INTO `players` (`pid`, `name`, `age`) VALUES
(1, 'Samual', 25),
(2, 'Vino', 20),
(3, 'John', 20),
(4, 'Andy', 22),
(5, 'Brian', 21),
(6, 'Dew', 24),
(7, 'Kris', 25),
(8, 'William', 26),
(9, 'George', 23),
(10, 'Peter', 19),
(11, 'Tom', 20),
(12, 'Andre', 20);

在MySQL查询获得排名函数

我们希望获得排名列升序的球员的年龄。所以我们的查询将会:

SELECT pid, name, age, @curRank := @curRank + 1 AS rank
FROM players p, (
SELECT @curRank := 0
) q
ORDER BY age

| PID |    NAME | AGE | RANK |
|-----|---------|-----|------|
|  10 |   Peter |  19 |    1 |
|  12 |   Andre |  20 |    2 |
|   2 |    Vino |  20 |    3 |
|   3 |    John |  20 |    4 |
|  11 |     Tom |  20 |    5 |
|   5 |   Brian |  21 |    6 |
|   4 |    Andy |  22 |    7 |
|   9 |  George |  23 |    8 |
|   6 |     Dew |  24 |    9 |
|   7 |    Kris |  25 |   10 |
|   1 |  Samual |  25 |   11 |
|   8 | William |  26 |   12 |

声明一个变量在mysql中必须使用‘@’变量名前签署。聽的 (@curRank := 0)在FROM子句允许我们变量初始化不需要单独设置命令。您可以使用 SET聽但它将处理两个查询:

SET @curRank := 0;
SELECT pid, name, age, @curRank := @curRank + 1 AS rank
FROM players
ORDER BY age

查询计算等级降序排列

更曾获得等级降序排列的年龄名字,修改聽查询 ORDER BY条款与 DESC和列名称:

SELECT pid, name, age, @curRank := @curRank + 1 AS rank
FROM players p, (
SELECT @curRank := 0
) q
ORDER BY age DESC, name

| PID |    NAME | AGE | RANK |
|-----|---------|-----|------|
|   8 | William |  26 |    1 |
|   7 |    Kris |  25 |    2 |
|   1 |  Samual |  25 |    3 |
|   6 |     Dew |  24 |    4 |
|   9 |  George |  23 |    5 |
|   4 |    Andy |  22 |    6 |
|   5 |   Brian |  21 |    7 |
|  12 |   Andre |  20 |    8 |
|   3 |    John |  20 |    9 |
|  11 |     Tom |  20 |   10 |
|   2 |    Vino |  20 |   11 |
|  10 |   Peter |  19 |   12 |

排名在MySQL行关系

现在如果我们希望聽分配相同的等级行有联系方式行比较列秩值相同(age在我们的例子中)应该持有相同的排名而计算排在MySQL。为此我们使用一个聽额外变量。

SELECT pid, name, age, 
CASE 
WHEN @prevRank = age THEN @curRank 
WHEN @prevRank := age THEN @curRank := @curRank + 1
END AS rank
FROM players p, 
(SELECT @curRank :=0, @prevRank := NULL) r
ORDER BY age

| PID |    NAME | AGE | RANK |
|-----|---------|-----|------|
|  10 |   Peter |  19 |    1 |
|  12 |   Andre |  20 |    2 |
|   2 |    Vino |  20 |    2 |
|   3 |    John |  20 |    2 |
|  11 |     Tom |  20 |    2 |
|   5 |   Brian |  21 |    3 |
|   4 |    Andy |  22 |    4 |
|   9 |  George |  23 |    5 |
|   6 |     Dew |  24 |    6 |
|   7 |    Kris |  25 |    7 |
|   1 |  Samual |  25 |    7 |
|   8 | William |  26 |    8 |

如图所示,当两个或两个以上行排在同一分区,每个系行收到相同的等级。球员安德烈,红酒,约翰和汤姆有相同的年龄所以排名2。有下一个最高年龄的玩家(Brian)是排名第三。这个查询聽聽相当于聽DENSE_RANK()函数在该软件和ORACLE。

排名()相当于MySQL

在使用等级()函数,如果两个或两个以上行并列排名,每个系行收到相同的等级,但是差距排名有关系。

SELECT pid, name, age, rank FROM
(SELECT pid, name, age,
@curRank := IF(@prevRank = age, @curRank, @incRank) AS rank, 
@incRank := @incRank + 1, 
@prevRank := age
FROM players p, (
SELECT @curRank :=0, @prevRank := NULL, @incRank := 1
) r 
ORDER BY age) s

这是查询的子查询。我们使用三个变量来计算排名的关系,忽略其他列在查询结果(@incRank, @prevRank, @curRank)我们有封闭的子查询查询。这是()函数可以在该软件和ORACLE。

| PID |    NAME | AGE | RANK |
|-----|---------|-----|------|
|  10 |   Peter |  19 |    1 |
|  12 |   Andre |  20 |    2 |
|   2 |    Vino |  20 |    2 |
|   3 |    John |  20 |    2 |
|  11 |     Tom |  20 |    2 |
|   5 |   Brian |  21 |    6 |
|   4 |    Andy |  22 |    7 |
|   9 |  George |  23 |    8 |
|   6 |     Dew |  24 |    9 |
|   7 |    Kris |  25 |   10 |
|   1 |  Samual |  25 |   10 |
|   8 | William |  26 |   12 |

在这里我们可以看到玩家聽安德烈,红酒,约翰和汤姆有相同的年龄所以排名2。聽有下一个最高年龄的玩家(Brian)是排名第六,而不是3,因为有四个聽行排名在位置2。

我希望在看到这些例子中,您将聽理解等级之间的差异()和DENSE_RANK()以及将知道去哪里在MySQL中使用查询来获取排名功能。

对目标列排序
设置一个变量作为排名值,在每条记录中自增 1
方案一:
SQL: (如果想要降序排名,可以改成 ORDER BY age DESC)

SELECT pid, name, age, @curRank := @curRank + 1 AS rank
FROM players p, (
SELECT @curRank := 0
) q
ORDER BY age

效果:(值相同,排名不同)

| PID |    NAME | AGE | RANK |
|-----|---------|-----|------|
|  10 |   Peter |  19 |    1 |
|  12 |   Andre |  20 |    2 |
|   2 |    Vino |  20 |    3 |
|   3 |    John |  20 |    4 |
|  11 |     Tom |  20 |    5 |
|   5 |   Brian |  21 |    6 |
|   4 |    Andy |  22 |    7 |
|   9 |  George |  23 |    8 |
|   6 |     Dew |  24 |    9 |
|   7 |    Kris |  25 |   10 |
|   1 |  Samual |  25 |   11 |
|   8 | William |  26 |   12 |

方案二:
SQL: (
暂存上一条记录的 age (@prevRank)。

如果当前 age 与其相等,使用与前一记录相同的排名;
否则排名加一,并更新 @prevRank
)

SELECT pid, name, age, @curRank := @curRank + 1 AS rank
FROM players p, (
SELECT @curRank := 0
) q
ORDER BY age DESC, name

效果:(值相同,排名也相同;排名值连续递增)

| PID |    NAME | AGE | RANK |
|-----|---------|-----|------|
|   8 | William |  26 |    1 |
|   7 |    Kris |  25 |    2 |
|   1 |  Samual |  25 |    3 |
|   6 |     Dew |  24 |    4 |
|   9 |  George |  23 |    5 |
|   4 |    Andy |  22 |    6 |
|   5 |   Brian |  21 |    7 |
|  12 |   Andre |  20 |    8 |
|   3 |    John |  20 |    9 |
|  11 |     Tom |  20 |   10 |
|   2 |    Vino |  20 |   11 |
|  10 |   Peter |  19 |   12 |

方案三:
SQL: (
增加一个变量(@incRank)用于记录序号(类似方案一)。

如果当前 age 与上一条记录相同,使用与前一记录相同的排名(类似方案二)
否则使用序号(@incRank)


SELECT pid, name, age, rank FROM
(SELECT pid, name, age,
@curRank := IF(@prevRank = age, @curRank, @incRank) AS rank, 
@incRank := @incRank + 1, 
@prevRank := age
FROM players p, (
SELECT @curRank :=0, @prevRank := NULL, @incRank := 1
) r 
ORDER BY age) s

效果:(值相同,排名也相同;排名值递增不连续)

| PID |    NAME | AGE | RANK |
|-----|---------|-----|------|
|  10 |   Peter |  19 |    1 |
|  12 |   Andre |  20 |    2 |
|   2 |    Vino |  20 |    2 |
|   3 |    John |  20 |    2 |
|  11 |     Tom |  20 |    2 |
|   5 |   Brian |  21 |    6 |
|   4 |    Andy |  22 |    7 |
|   9 |  George |  23 |    8 |
|   6 |     Dew |  24 |    9 |
|   7 |    Kris |  25 |   10 |
|   1 |  Samual |  25 |   10 |
|   8 | William |  26 |   12 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值