Порядок по следующему наибольшему числу

#mysql #sql #sql-order-by

#mysql #sql #sql-порядок по

Вопрос:

У меня есть запрос, который определяет рейтинг игроков в нескольких упражнениях. В случае, если их оценки равны, мне нужно развязать по наивысшему рейтингу в каждом упражнении.

Пример:

      total_points pos1 pos2 pos3
#1   5            1    3    1
#2   7            3    1    3
#3   7            4    1T   2
  

На 2-м месте будет игрок, который в настоящее время находится на 3-м месте, потому что у него 1-е место связано с игроком на 2-м месте, но у него 2-е место как следующее выше, в то время как у игрока, который находится на втором месте, следующий выше 3. (T означает связанный и должен появиться следующимдля нумерации, когда игрок сыграл вничью с другим)

Итак, желаемый результат

   total_points pos1 pos2 pos3
#1   5            1    3    1
#2   7            4    1T   2
#3   7            3    1    3
  

Я думаю, что порядок упорядочивается по pos1, а затем игнорирует другие позиции?

Последующий запрос, который я использую, это

  SELECT totals.*, scores.*, warriors.*, results.*, positions.* 
       FROM (SELECT results . * , SUM( points ) AS total_points 
           FROM final_results AS results 
           INNER JOIN contest_trainings AS wods ON wods.id = results.wod_id 
           WHERE wods.show_date < NOW( ) 
           GROUP BY contest_id) AS totals, 
       final_results AS scores 
       INNER JOIN (
           SELECT wod1.*, wod1.wod_position AS pos1, wod2.wod_position AS pos2, wod3.wod_position AS pos3 
           FROM final_results AS wod1 
           LEFT OUTER JOIN final_results AS wod2 
           ON wod1.contest_id = wod2.contest_id 
           AND wod2.wod_id > wod1.wod_id 
           LEFT OUTER JOIN final_results AS wod3 
           ON wod2.contest_id = wod3.contest_id 
           AND wod3.wod_id > wod2.wod_id 
           GROUP BY wod1.contest_id) as positions 
        ON positions.contest_id = scores.contest_id 
        INNER JOIN contest AS warriors ON scores.contest_id = warriors.id 
        INNER JOIN contest_results AS results ON scores.contest_id = results.contest_id 
        WHERE totals.contest_id = warriors.id AND results.validated = 1 
        AND warriors.battle = 1 
        AND warriors.category = 1 
        GROUP BY scores.contest_id 
        ORDER BY totals.total_points, 
        positions.pos1, CAST(positions.pos2 AS UNSIGNED), positions.pos3
  

Комментарии:

1. Является ли T в исходной таблице, поскольку я не могу определить, что оно добавляется в SQL? Если это так, вам, вероятно, нужно удалить его, иначе MySQL, вероятно, выполнит сравнение символов. Попробуйте преобразовать его в int (т.Е.). CAST(ifnull(positions.pos2,0) AS UNSIGNED)

2. @Kickstart В итоге у меня получилось лучше всего, что на самом деле не было задумано. Отредактировано, чтобы соответствовать желаемому результату. Приведение строки к int, к сожалению, не внесло никаких изменений в вывод

3. Не уверен, что вы можете делать то, что хотите. Похоже, вы хотите выбрать порядок сортировки в зависимости от значений с обеих сторон (но записи с обеих сторон будут меняться по мере выполнения сортировки). Однако я немного сбит с толку, поскольку в ваших оригинальных примерах вы ссылаетесь на привязку к 1-му месту , но, похоже, это относится к столбцу pos2. Этот столбец имеет отношение к порядку только в том случае, если столбец pos1 совпадает, а его здесь нет.

4. Извините за путаницу. Концепция заключается в том, что чем меньше очков вы получите, тем лучше. Вы получаете X очков за позицию, которую вы занимаете в каждом упражнении (1,2,3). Если вы пришли первым в упражнении 1, вы получаете 1 очко, если вы пришли 3-м в упражнении 2, вы получаете 3 очка и так далее. Сумма ваших очков определит ваше турнирное положение. Однако, если вы с кем-то сыграете вничью (столько же очков, сколько у другого игрока) Мне нужно развязать, и критерием является то, что игрок, у которого было лучшее положение в каждом упражнении, приходит первым. Если я занимаю первое место с 1 1 4 (6 очков) с кем-то, у кого 2 1 3, я выигрываю, потому что я стал первым в более

5. Это говорит о том, что данные вашего примера не совсем такие, как вы хотите. Для 2-й и 3-й строк оба имеют одинаковые общие баллы. У одного pos1 из 4, а у другого pos1 из 3. Тот, у которого pos1 из 3, должен предшествовать тому, у которого pos1 из 4, но в ваших желаемых результатах отображается наоборот.

Ответ №1:

Предполагая, что вас интересует до 4-й позиции, я бы попробовал следующую сортировку:-

 SELECT totals.*, scores.*, warriors.*, results.*, positions.* 
FROM 
(
    SELECT results . * , SUM( points ) AS total_points 
    FROM final_results AS results 
    INNER JOIN contest_trainings AS wods 
    ON wods.id = results.wod_id 
    WHERE wods.show_date < NOW( ) 
    GROUP BY contest_id
) AS totals, 
CROSS JOIN final_results AS scores 
INNER JOIN 
(
    SELECT wod1.*, wod1.wod_position AS pos1, wod2.wod_position AS pos2, wod3.wod_position AS pos3 
    FROM final_results AS wod1 
    LEFT OUTER JOIN final_results AS wod2 
    ON wod1.contest_id = wod2.contest_id 
    AND wod2.wod_id > wod1.wod_id 
    LEFT OUTER JOIN final_results AS wod3 
    ON wod2.contest_id = wod3.contest_id 
    AND wod3.wod_id > wod2.wod_id 
    GROUP BY wod1.contest_id
) as positions 
ON positions.contest_id = scores.contest_id 
INNER JOIN contest AS warriors ON scores.contest_id = warriors.id 
INNER JOIN contest_results AS results ON scores.contest_id = results.contest_id 
WHERE totals.contest_id = warriors.id AND results.validated = 1 
AND warriors.battle = 1 
AND warriors.category = 1 
GROUP BY scores.contest_id 
ORDER BY totals.total_points, 
        IF(positions.pos1 = 1, 1, 0)   IF(positions.pos2 = 1, 1, 0)   IF(positions.pos3 = 1, 1, 0),
        IF(positions.pos1 = 2, 1, 0)   IF(positions.pos2 = 2, 1, 0)   IF(positions.pos3 = 2, 1, 0),
        IF(positions.pos1 = 3, 1, 0)   IF(positions.pos2 = 3, 1, 0)   IF(positions.pos3 = 3, 1, 0),
        IF(positions.pos1 = 4, 1, 0)   IF(positions.pos2 = 4, 1, 0)   IF(positions.pos3 = 4, 1, 0)
  

Возможно, это можно было бы улучшить, но мне нужно было бы увидеть больше ваших оригинальных таблиц.

Обратите внимание, что ваш запрос, похоже, может иметь некоторые неопределенные результаты. Например, ваш первый подзапрос выполняет ГРУППУ ПО contest_id, но возвращает все из таблицы final_results . Не уверен, что все эти столбцы зависят от одного значения contest_id (но не могу быть уверен, поскольку я не знаю, как выложены final_results и contest_trainings).

Комментарии:

1. Спасибо за ответ. К сожалению, я не могу контролировать, сколько записей будет в БД, поэтому это сильно ограничивает доступ только к 4-й позиции. Я постараюсь переформулировать вопрос как можно скорее, чтобы у всех было лучшее понимание. Еще раз спасибо

2. Существует ли максимальное значение полей pos?