Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL-在select上获取行号_Mysql_Sql_Row Number - Fatal编程技术网

MySQL-在select上获取行号

MySQL-在select上获取行号,mysql,sql,row-number,Mysql,Sql,Row Number,如果项目已排序,是否可以运行select语句并获取行号 我有一张这样的桌子: mysql> describe orders; +-------------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+-------------

如果项目已排序,是否可以运行select语句并获取行号

我有一张这样的桌子:

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不在字段列表中时不起作用吗?见我的结果: