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

Сегодня я потратил довольно много времени, пробуя разные вещи, но ни одна из них, похоже, не работает. Вот моя ситуация, я хотел бы иметь возможность выбирать ранг строки на основе ее идентификатора из специально отсортированной строки

Например, если мой запрос выглядит примерно так:

SELECT id, name FROM people ORDER BY name ASC

с такими результатами, как:

id   name
3    Andrew
1    Bob
5    Joe
4    John
2    Steve

Я хотел бы получить ранг (какая строка оказывается в результатах), не возвращая все строки и не зацикливая их, пока не доберусь до того, который хочу (в PHP).

Например, я хотел бы выбрать «ранг» «Стива», чтобы он возвращал — в данном случае — 5 (не его идентификатор, а «ранг» его имени в приведенном выше запросе).

Точно так же я хотел бы иметь возможность выбрать ранг любой строки с идентификатором 1. В этом примере я хотел бы вернуть «ранг» 2 (потому что это в какой строке результата есть идентификатор 1) и ничего больше.

Я гуглил столько, сколько мог, с разными результатами... либо с очень медленными запросами для больших таблиц, либо с необходимостью создавать всевозможные временные таблицы и пользовательские переменные (первое я ДЕЙСТВИТЕЛЬНО хотел бы избежать, последнее думаю жить можно))

Любая помощь или понимание будет принята с благодарностью.


person theotherlight    schedule 11.08.2009    source источник


Ответы (4)


из artfulsoftware:

SELECT p1.id, p1.name, COUNT( p2.name ) AS Rank
    FROM people p1
    JOIN people p2 
    ON p1.name < p2.name
    OR (
         p1.name = p2.name
         AND p1.id = p2.id
    )
GROUP BY p1.id, p1.name
ORDER BY p1.name DESC , p1.id DESC
LIMIT 4,1
person bjelli    schedule 11.08.2009
comment
После нескольких небольших изменений это, кажется, чертовски хорошо работает для того, что мне нужно. Однако есть одно дополнительное осложнение: можно ли выбрать набор строк с заданным набором условий (например, только люди, в имени которых есть буква «J» -- WHERE name LIKE «%j%». Я попробовал это , и хотя поле результата «ранг» по-прежнему актуально, оно пропускает числа для тех, в имени которых нет буквы J. Мысли? - person theotherlight; 12.08.2009

Что-то вроде этого?

SELECT Row, id, name
FROM (SELECT @row := @row + 1 AS Row, id, name
      FROM people
      ORDER BY name ASC)
WHERE Row = @SomeRowNumber

Если вы хотите использовать идентификатор, просто измените предложение where.

person Brandon    schedule 11.08.2009
comment
Это дает ошибку, что каждая производная таблица должна иметь свой собственный псевдоним @Brandon - person Amanjot Kaur; 18.08.2016

Попробуй это:

SELECT @rownum:=@rownum+1 `rank`, p.id, p.name
FROM people p, (SELECT @rownum:=0) r
ORDER BY name ASC
person Plutor    schedule 11.08.2009
comment
Это похоже на то, что я ранее придумал с помощью Google, и это прекрасно работает, если мне нужен «ранг» каждой строки в моей таблице, но что, если мне нужен только ранг одной строки? Я попробовал что-то вроде ‹pre› SELECT @rownum:=@rownum+1 rank, p.id, p.name FROM people p, (SELECT @rownum:=0) r WHERE id = 5 ORDER BY name ASC ‹/pre› Но это всегда будет давать мне ранг 1 (потому что он всегда возвращает только один результат). Есть ли способ получить один ранг одной строки на основе всех результатов запроса? Я надеюсь это имеет смысл. - person theotherlight; 11.08.2009
comment
как получить только одну запись с этим конкретным рангом, используя ваш запрос @Plutor - person Amanjot Kaur; 18.08.2016

Я пытаюсь использовать этот код ... может помочь другим. Я получаю результат от пользователей и загружаю таблицу для изображения профиля пользователя и присоединяюсь к ней, чем после того, как я вычисляю пользовательские баллы и сортирую их. Наконец-то проверяю и добавляю номер строки для ранжирования пользователей... Наслаждайтесь. Спасибо

set @row_num = 0;
set @calp =0;
select  if(@calp=(@calp:=user.cal_points), @row_num, @row_num := @row_num + 1) as row_number,user.* from 
(select user_skills.*,users.username,upload.file_name from user_skills join users on user_skills.user_id=users.id join upload on upload.upload_id=users.profile_pic order by user_skills.cal_points desc) as user
WHERE user.skill_name LIKE  '%ph%'
person Kamlesh    schedule 07.08.2014