Запрос MySQL помогает найти ранг по идентификатору

#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 и посмотрите, получите ли вы те же результаты. Держу пари, вы этого не сделаете…