С MySQL, как я могу создать столбец, содержащий индекс записи в таблице?

Есть ли способ получить фактический номер строки из запроса?

Я хочу иметь возможность заказать таблицу под названием league_girl в поле под названием score; и верните имя пользователя и фактическую позицию строки этого имени пользователя.

Я хочу ранжировать пользователей, чтобы я мог указать, где находится конкретный пользователь, т.е. Джо - позиция 100 из 200, т.е.

User Score Row
Joe  100    1
Bob  50     2
Bill 10     3

Я видел несколько решений здесь, но я пробовал большинство из них, и никто из них не вернул номер строки.

Я пробовал это:

SELECT position, username, score
FROM (SELECT @row := @row + 1 AS position, username, score 
       FROM league_girl GROUP BY username ORDER BY score DESC) 

Как получено

... но, похоже, он не возвращает позицию строки.

Любые идеи?

Ответ 1

Вы можете попробовать следующее:

SELECT  l.position, 
        l.username, 
        l.score,
        @curRow := @curRow + 1 AS row_number
FROM    league_girl l
JOIN    (SELECT @curRow := 0) r;

Часть JOIN (SELECT @curRow := 0) позволяет инициализировать переменную без отдельной команды SET.

Тестовый пример:

CREATE TABLE league_girl (position int, username varchar(10), score int);
INSERT INTO league_girl VALUES (1, 'a', 10);
INSERT INTO league_girl VALUES (2, 'b', 25);
INSERT INTO league_girl VALUES (3, 'c', 75);
INSERT INTO league_girl VALUES (4, 'd', 25);
INSERT INTO league_girl VALUES (5, 'e', 55);
INSERT INTO league_girl VALUES (6, 'f', 80);
INSERT INTO league_girl VALUES (7, 'g', 15);

Тестовый запрос:

SELECT  l.position, 
        l.username, 
        l.score,
        @curRow := @curRow + 1 AS row_number
FROM    league_girl l
JOIN    (SELECT @curRow := 0) r
WHERE   l.score > 50;

Результат:

+----------+----------+-------+------------+
| position | username | score | row_number |
+----------+----------+-------+------------+
|        3 | c        |    75 |          1 |
|        5 | e        |    55 |          2 |
|        6 | f        |    80 |          3 |
+----------+----------+-------+------------+
3 rows in set (0.00 sec)

Ответ 2

SELECT @i:[email protected]+1 AS iterator, t.*
FROM tablename t,(SELECT @i:=0) foo

Ответ 3

Вот структура используемого шаблона:

  select
          /*this is a row number counter*/
          ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
          as rownumber,
          d3.*
  from 
  ( select d1.* from table_name d1 ) d3

И вот мой рабочий код:

select     
           ( select @rownum := @rownum + 1 from ( select @rownum := 0 ) d2 ) 
           as rownumber,
           d3.*
from
(   select     year( d1.date ), month( d1.date ), count( d1.id )
    from       maindatabase d1
    where      ( ( d1.date >= '2013-01-01' ) and ( d1.date <= '2014-12-31' ) )
    group by   YEAR( d1.date ), MONTH( d1.date ) ) d3

Ответ 4

Вы также можете использовать

SELECT @curRow := ifnull(@curRow,0) + 1 Row, ...

для инициализации переменной счетчика.

Ответ 5

Предполагая, что MySQL поддерживает его, вы можете легко сделать это со стандартным подзапросом SQL:

select 
    (count(*) from league_girl l1 where l2.score > l1.score and l1.id <> l2.id) as position,
    username,
    score
from league_girl l2
order by score;

Для большого количества отображаемых результатов это будет немного медленным, и вы захотите переключиться на самостоятельное соединение.

Ответ 6

Если вы просто хотите узнать позицию одного конкретного пользователя после заказа по счету поля, вы можете просто выбрать всю строку из своей таблицы, где оценка поля выше, чем текущая оценка пользователя. И используйте номер строки, возвращенный + 1, чтобы узнать, какая позиция этого текущего пользователя.

Предполагая, что ваша таблица "league_girl", а ваше основное поле - "id", вы можете использовать это:

SELECT count(id) + 1 as rank from league_girl where score > <your_user_score>

Ответ 7

Я знаю, что OP запрашивает ответ mysql, но поскольку я нашел, что другие ответы не работают для меня,

  • Большинство из них терпят неудачу с order by
  • Или они просто очень неэффективны и делают ваш запрос очень медленным для толстой таблицы

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

пример в PHP:

        $users = UserRepository::loadAllUsersAndSortByScore();

        foreach($users as $index=>&$user){
            $user['rank'] = $index+1;
        }

пример в PHP с использованием смещения и ограничения для подкачки:

        $limit = 20; //page size
        $offset = 3; //page number

        $users = UserRepository::loadAllUsersAndSortByScore();

        foreach($users as $index=>&$user){
            $user['rank'] = $index+1+($limit*($offset-1));
        }