Переменные MySQL во вложенных подзапросах
В настоящее время я работаю над платформой электронного обучения, которая содержит модуль курсов и экзаменов. Идея в том, что за курсом следует экзамен. Пользователь может выполнить экзамен несколько раз (в зависимости от настроек в таблице экзаменов). У меня есть модуль, в котором мне нужно определить, следует ли перенаправлять пользователя на страницу экзамена или статистики. Если пользователь не использовал все свои попытки, его следует перенаправить на экзамен, в противном случае - на статистику.
Итак, вот мой запрос (немного упрощенный, поскольку все условия и соединения внешнего запроса здесь не имеют значения), который должен определить, куда идти.
SELECT
@course_id := courses.id as id,
IF(
(SELECT X.attempts_count FROM
(SELECT
COUNT(exams_attempts.id) as attempts_count,
@max_attempts := exams.max_attempts
FROM exams
LEFT JOIN exams_attempts ON exams.id = exams_attempts.quiz_id
JOIN users ON exams_attempts.user_id = users.id
WHERE exams_attempts.user_id = 12
AND exams_attempts.course_id = @course_id
HAVING attempts_count >= @max_attempts) as X
),
'stats',
'exam'
) as redirect
FROM courses
WHERE courses.id = 1
Из соображений тестирования я ограничил курсы статическим значением, но при фактическом использовании это большое количество курсов для поиска.
И наконец - я обнаружил, что это работает на локальном хосте, но не на сервере, несмотря на ту же версию MySql. Я хотел бы знать, есть ли какая-либо настройка, которая препятствует правильному выполнению моего запроса. Также я хотел бы знать, что вы предлагаете, может быть, моя идея не очень хорошая, и я мог бы перестроить этот запрос?
1 ответ
Это можно заставить работать.
Сделка заключается в следующем понятии из руководства " Пользовательские переменные":
В следующем утверждении вы можете подумать, что MySQL сначала вычислит @a, а затем выполнит присваивание:
SELECT @a, @a:=@a+1, ...;
Однако порядок вычисления для выражений с участием пользовательских переменных не определен.
И с переменной чисткой. Смотрите блог Барона, который является Обязательным Чтением. Рассмотрим вложенные операторы if и использование least()
, greatest()
, а также coalesce()
это такие усилия для безопасной обработки переменных.
Многие из них mysql-variables
вопросы могут занять некоторое время, чтобы написать безопасно. Как час или полдня. Простое получение правильного ответа не эквивалентно производственному коду. Некоторое время назад я создал тег для размещения их, так как я перехожу в них или пишу несколько.