#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?