MySQL - получить номер строки при выборе - PullRequest
171 голосов
/ 26 марта 2010

Можно ли запустить оператор выбора и получить номер строки, если элементы отсортированы?

У меня есть такая таблица:

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

Затем я могу выполнить этот запрос, чтобы получить количество заказов по идентификатору:

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

Это дает мне счет каждого itemID в таблице, как это:

+--------+------------+
| 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)

Ответы [ 4 ]

172 голосов
/ 26 марта 2010

Взгляните на это .

Измените ваш запрос на:

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

Последний выбор - ваш счет.

170 голосов
/ 17 декабря 2010
SELECT @rn:=@rn+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;
27 голосов
/ 24 апреля 2015

Решение Swamibebop работает, но используя синтаксис table.*, мы можем избежать повторения имен столбцов внутреннего select и получить более простой / более короткий результат:

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;
10 голосов
/ 26 марта 2010

Вы можете использовать переменные MySQL, чтобы сделать это. Нечто подобное должно работать (хотя оно состоит из двух запросов).

SELECT 0 INTO @x;

SELECT itemID, 
       COUNT(*) AS ordercount, 
       (@x:=@x+1) AS rownumber 
FROM orders 
GROUP BY itemID 
ORDER BY ordercount DESC; 
...