#mysql #sql #ranking
#mysql #sql #Рейтинг
Вопрос:
Я пытаюсь изменить следующий запрос, чтобы найти ранг определенного видеоида, и мне не очень везет, может кто-нибудь предложить решение?
SELECT videoid wins/loses as win_loss,
@curRank := @curRank 1 AS rank
FROM cb_video,
(SELECT @curRank := 0) r
ORDER BY wins/loses DESC
Я пытался выполнить подобный подзапрос, но это не удается:
SELECT rank
FROM (SELECT videoid wins/loses as win_loss,
@curRank := @curRank 1 AS rank
FROM cb_video,
(SELECT @curRank := 0) r
ORDER BY wins/loses DESC)
WHERE videoid = 116
Также добавление videoid в предложение WHERE без подзапроса просто всегда показывает, что ранг является позицией # 1, поскольку он возвращает только одну строку:
SELECT videoid wins/loses as win_loss,
@curRank := @curRank 1 AS rank
FROM cb_video,
(SELECT @curRank := 0) r
WHERE videoid = 116
ORDER BY wins/loses DESC
Есть идеи, как ограничить результат определенным идентификатором, но при этом сохранить ранг? К вашему сведению, я сохраняю две колонки (выигрыши и проигрыши), если это поможет.
Комментарии:
1. Ваш второй подход кажется мне правильным. Какую ошибку вы получили?
2. IME, функциональности переменной rank нельзя доверять, если механизм обработки таблиц — MyISAM. Числа пропускаются…
Ответ №1:
SELECT a.videoid,
(SELECT COUNT(*) FROM cb_video b
WHERE a.videoid !=b.videoid
AND (b.wins/b.loses) > (a.wins/a.loses)) 1 AS rank
FROM cb_video a
WHERE a.videoid = 116
Комментарии:
1. a1ex07, похоже, это работает, однако меня интересует, как вы используете коэффициент выигрыша-проигрыша. Ваш запрос возвращает рейтинг 6, в то время как запрос Arek ниже возвращает рейтинг 8.
2. Это потому, что мой запрос возвращает количество записей, в которых коэффициент больше текущего. Например, если у нас есть 4 записи, выигрыш / проигрыш которых равен 3,3,2,2, мой запрос возвращает ранг = 3 для последней записи, Arek — 4. После выполнения моего запроса вы получите два ранга 1 и 2 ранга = 3
3. Это приведет к дублированию значений ранга при одинаковом соотношении — это похоже на использование аналитического,
DENSE_RANK
а неROW_NUMBER
.4. То, что является правильным, зависит от того, что вы ищете… Ваш второй подход (исправленный Ареком Яблонски) не возвращает ранг, он возвращает номер строки.
5. Не пробелы, просто ранг будет повторяться. IE: Если две записи претендуют на второе место, их значение ранга будет равно «2».
Ответ №2:
Попробуйте что-то вроде этого:
SELECT videoid, rank FROM (SELECT videoid, wins/loses as win_loss, @curRank := @curRank 1 AS rank FROM cb_video, (SELECT @curRank := 0) r ORDER BY wins/loses DESC) s WHERE videoid = 116
Комментарии:
1. Это тоже работает. Ваш возвращает рейтинг 8. Я пытаюсь выяснить, какой из них точнее ваш или a1ex07s выше.
Ответ №3:
Я протестировал это на простом подмножестве, созданном из аналогичной таблицы, как вы описали… Он возвращает ОДНО видео и его фактический конечный рейтинг из всего набора…
select *
from ( SELECT
videoid,
wins,
losses,
wins/losses,
@curRank := @curRank 1 Rank
FROM
cb_video,
( select @curRank := 0 ) r
order by
wins/losses desc ) PreQuery
where
PreQuery.VideoID = 116
Комментарии:
1. Измените механизм обработки таблиц на MyISAM и посмотрите, получите ли вы те же результаты. Держу пари, вы этого не сделаете…