2010-03-26 78 views
150

如果项目已排序,我可以运行select语句并获取行号吗?MySQL - 获取行号

我有这样的一个表:

SELECT itemID, COUNT(*) as ordercount 
FROM orders 
GROUP BY itemID ORDER BY ordercount DESC; 

这让我在每个itemID的计数:

mysql> describe orders; 
+-------------+---------------------+------+-----+---------+----------------+ 
| Field  | Type    | Null | Key | Default | Extra   | 
+-------------+---------------------+------+-----+---------+----------------+ 
| orderID  | bigint(20) unsigned | NO | PRI | NULL | auto_increment | 
| itemID  | bigint(20) unsigned | NO |  | NULL |    | 
+-------------+---------------------+------+-----+---------+----------------+ 

然后我就可以运行此查询通过ID来获得的订单数这样的表:

+--------+------------+ 
| itemID | ordercount | 
+--------+------------+ 
| 388 |   3 | 
| 234 |   2 | 
| 3432 |   1 | 
| 693 |   1 | 
| 3459 |   1 | 
+--------+------------+ 

我想要得到行号,所以我可以告诉itemID=388是第一行,234是第二等,(基本上是订单的排名,而不仅仅是一个原始计数)。我知道当我得到结果集时,我可以用Java来做到这一点,但我想知道是否有办法纯粹用SQL来处理它。

更新

设置排名将其添加到结果集,但不能正常下令:

mysql> SET @rank=0; 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT @rank:[email protected]+1 AS rank, itemID, COUNT(*) as ordercount 
    -> FROM orders 
    -> GROUP BY itemID ORDER BY rank DESC; 
+------+--------+------------+ 
| rank | itemID | ordercount | 
+------+--------+------------+ 
| 5 | 3459 |   1 | 
| 4 | 234 |   2 | 
| 3 | 693 |   1 | 
| 2 | 3432 |   1 | 
| 1 | 388 |   3 | 
+------+--------+------------+ 
5 rows in set (0.00 sec) 
+1

为了将来的参考:如果你想从秩1到秩5排序,使用'ORDER BY秩ASC'(按ASCending顺序排列)。我想这就是你的意思*,但没有正确的命令* – GroundZero 2015-01-09 12:57:23

+0

[ROW \ _NUMBER()在MySQL中可能的重复](http://stackoverflow.com/questions/1895110/row-number-in-mysql) – 2016-05-25 14:13:48

回答

147

看看this

查询更改为:

SET @rank=0; 
SELECT @rank:[email protected]+1 AS rank, itemID, COUNT(*) as ordercount 
    FROM orders 
    GROUP BY itemID 
    ORDER BY ordercount DESC; 
+1

将结果集添加到结果集中,但不会将结果集置于正确的顺序 - 更新结果的问题 – George 2010-03-26 00:22:14

+1

尝试保留'ORDER BY ordercount DESC',然后将整个查询包装在另一个'SELECT'中,第一个,但排名列(在这种情况下为0)。 – 2010-03-26 00:27:13

+1

你能举一个这样的例子吗?我将如何包装选择? – George 2010-03-27 18:21:11

9

您可以使用MySQL变量来做到这一点。像这样的东西应该可以工作(但是,这是两个查询)。

SELECT 0 INTO @x; 

SELECT itemID, COUNT(*) as ordercount, (@x:[email protected]+1) as rownumber FROM orders GROUP BY itemID ORDER BY ordercount DESC; 
+0

小心,这将无法正常工作,因为'** by'会在**变量'@ x'已被评估后发生**。尝试使用其他列进行排序试验。同时试验'desc'和'asc'。你会看到很多次他们会失败,并且只有当它工作时,它是**纯粹的运气**,因为你原来的“select”顺序与order by顺序相同。查看我的解决方案和/或Swamibebop的解决方案。 – Pacerier 2015-04-24 11:43:16

+0

@Pacerier你确定吗?我已经厌倦了其他示例中的类似查询(基本上从数字列中进行选择,并根据它们的顺序对它们进行编号),似乎如果我通过var/row num排序,当它更改结果行的顺序时,但每个号码都有相同的行号。但是如果我通过数字列进行排序,那么'ASC' /'DESC'会改变这些数字编号的顺序(从最小到最大,反之亦然)。所以看起来在这种情况下,首先评估'order by'。 – 2016-12-17 17:42:11

157
SELECT @rn:[email protected]+1 AS rank, itemID, ordercount 
FROM (
    SELECT itemID, COUNT(*) AS ordercount 
    FROM orders 
    GROUP BY itemID 
    ORDER BY ordercount DESC 
) t1, (SELECT @rn:=0) t2; 
+0

感谢澄清,这解决了我遇到的无序问题。 – thaddeusmt 2011-03-29 18:49:10

+1

谢谢,这对我来说真的很有用:)我很惊讶没有一种更直接的方式从结果集中获取行'索引'......但无论如何感谢这很方便。 – rat 2012-01-05 17:22:06

+0

您可以通过更改SELECT \ @rn:= \ @ rn + 1 AS rank,itemID,ordercount,\ @tot:= \ @ tot + ordercount as totalcount中的第一个select语句来添加第四行增量totalcount。要定义\ @tot的初始值,应该在t2之后添加:(SELECT \ @tot:= 0)t3。在每个\ @之前删除\,我必须使用它来规避迷你Markdown格式。 – 2014-04-26 00:22:45

21

Swamibebop的解决方案工作,但通过采取table.*语法的优势,我们可以avoid repeatingselect的列名,并得到一个简单的/更短的结果:

select @r := @r+1 , z.* from(

    /* your original select statement goes in here */ 

)z, (select @r:=0)y; 

所以那会给你:

select @r := @r+1 , z.* from(

    select itemID, count(*) as ordercount 
    from orders 
    group by itemID 
    order by ordercount desc 

)z, (select @r:=0)y; 
+0

这就像我需要的冠军。谢谢! – user2020930 2016-03-05 14:31:52

+0

谢谢!运行得非常好!谢谢! – 2016-03-16 07:42:50

+0

你是否偶然知道为什么在select语句中使用'@r:= @r + 1'工作,但是如果它在存储过程中使用'declare r int;设置r = 0;',它抱怨(在'r:= r + 1'上)? – 2016-12-17 17:03:01