Переменные 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 вопросы могут занять некоторое время, чтобы написать безопасно. Как час или полдня. Простое получение правильного ответа не эквивалентно производственному коду. Некоторое время назад я создал тег для размещения их, так как я перехожу в них или пишу несколько.

Другие вопросы по тегам