MySQL-在select上获取行号
如果项目已排序,是否可以运行select语句并获取行号 我有一张这样的桌子:MySQL-在select上获取行号,mysql,sql,row-number,Mysql,Sql,Row Number,如果项目已排序,是否可以运行select语句并获取行号 我有一张这样的桌子: mysql> describe orders; +-------------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+-------------
mysql> describe orders;
+-------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------------+------+-----+---------+----------------+
| orderID | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| itemID | bigint(20) unsigned | NO | | NULL | |
+-------------+---------------------+------+-----+---------+----------------+
+--------+------------+
| itemID | ordercount |
+--------+------------+
| 388 | 3 |
| 234 | 2 |
| 3432 | 1 |
| 693 | 1 |
| 3459 | 1 |
+--------+------------+
然后,我可以运行此查询以按ID获取订单数:
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 | |
+-------------+---------------------+------+-----+---------+----------------+
+--------+------------+
| 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:=@rank+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)
看一看
将查询更改为:
SET @rank=0;
SELECT @rank:=@rank+1 AS rank, itemID, COUNT(*) as ordercount
FROM orders
GROUP BY itemID
ORDER BY ordercount DESC;
SELECT @rank;
最后一个选择是您的计数。您可以使用MySQL变量来完成此操作。不过,类似的方法应该可以工作,它由两个查询组成
SELECT 0 INTO @x;
SELECT itemID,
COUNT(*) AS ordercount,
(@x:=@x+1) AS rownumber
FROM orders
GROUP BY itemID
ORDER BY ordercount DESC;
Swamibebop的解决方案是可行的,但通过利用table.*语法,我们可以选择内部的列名并获得更简单/更短的结果:
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;
它现在内置于MySQL 8.0和MariaDB 10.2中:
SELECT
itemID, COUNT(*) as ordercount,
ROW_NUMBER OVER (PARTITION BY itemID ORDER BY rank DESC) as rank
FROM orders
GROUP BY itemID ORDER BY rank DESC
这会将秩添加到结果集中,但不会将它们放在正确的顺序中-使用results更新问题尝试按ordercount DESC保持顺序,然后将整个查询包装在另一个SELECT中,该SELECT获取第一个查询的所有内容,但在本例中按秩列0排序。您可以显示一个示例吗?我该如何包装这些选择?看看swamibebop的answer@MikeCialowicz这请参阅我的解决方案或Swamibebop的解决方案以获得正确答案。感谢您的澄清,这解决了我遇到的无序问题。谢谢,这对我非常有用:我很惊讶没有更直接的方法从结果集中获取行“索引”。。。但无论如何,这很方便。您可以通过将select\@rn:=\@rn+1中的第一个select语句更改为rank、itemID、ordercount、\@tot:=\@tot+ordercount作为totalcount,来添加第四行的增量totalcount。要定义\@tot的初始值,应将其添加到t2:选择\@tot:=0 t3之后。删除\ before every\@,我必须使用它来规避迷你标记格式。有人能解释t1和t2的相关性吗?@Jared,MySQL语法只是需要一些东西。它可以是任何东西,甚至是x和y。供将来参考:如果您想从秩1到秩5排序,请使用按秩排序ASC以升序按秩排序。我猜这就是你的意思,但没有正确排序小心的可能重复,这不会起作用,因为排序比发生在变量@x计算之后。尝试使用其他列进行排序。还可以同时使用desc和asc进行试验。你会看到很多次他们都会失败,而且只有在成功的时候,这纯粹是运气使然,因为你最初选择的顺序与order by的顺序相同。查看我的解决方案和/或Swamibebop的解决方案。@Pacerier你确定吗?在另一个例子中,我已经厌倦了类似的查询,基本上是从数字列中选择,并根据它们的顺序对它们进行编号。如果我按var/row num排序,当它改变结果行的顺序时,每个数字都有相同的row num。但是如果我按number列排序,然后ASC/DESC将更改这些数字从最小到最大的编号顺序,反之亦然。在这种情况下,order by是首先计算的。您是否碰巧知道为什么在select语句中使用@r:=@r+1是有效的,但如果它在具有declare r int的存储过程中;设置r=0;,它抱怨r:=r+1?@Pacerier,第二次选择的行的顺序是否也有保证?我知道select WITH order by子句返回的行的顺序在任何地方都不能保证,最外层的select就是这样,尽管它是从内部有序的select中选择的,所以它可能是一个例外。但是,如果不是,我看不出这是一个正确的解决方案,因为它与Chibu的Mike有相同的缺陷-不保证order select将通过记录并对其进行编号。你知道为什么order BY不在字段列表中时不起作用吗?见我的结果: