Я предполагаю, что вы хотите запрос, который расскажет, каким будет следующий урок для конкретного учащегося для данного семестра, или пустым, если для этого учащегося больше нет занятий для этого учащегося.Результат должен быть одной строкой или нулем.
Чтобы сделать это с какой-либо эффективностью (и ИМХО здравым смыслом), вам нужно сначала пересмотреть структуру таблицы и предположения о ваших данных.Исходя из структур таблиц, которые вы предоставили, и того, как вы описали номера уроков, я предполагаю, что, например, будет 1 класс, уроки 1, 2, 3, ..., 10, 11, ... 20, 21, ..., 30, а затем класс 2, уроки 1 ... 30, а затем класс 3, уроки 1 ... 30 и т. Д. Кроме того, уроки 1-10 для каждого класса соответствуют термину 1, 11-20, к термину 2, и 21-30 к термину 3. Наконец, термины завершаются в порядке - урок 10 класса 3 завершается перед уроком 11 класса 1.
Сначала, вместо того, чтобы использовать номер вашего класса в качестве обоихуникальный идентификатор и порядковый номер (класс 1 встречается раньше, чем класс 2 и т. д.), я бы предложил поле уникального идентификатора (возможно, с автоматическим приращением) и отдельное поле class_num для порядкового номера.(Это менее критично для таблицы классов, чем для таблицы уроков, описанной далее.)
Далее, и аналогично, уроки должны получать поле уникального идентификатора отдельно от поля номера урока.Идентификатор будет PK.Этот уникальный идентификатор необходим, чтобы значительно упростить требуемый запрос, а также любые другие запросы, которые могут вам понадобиться.Без этого вы имеете дело с составным ключом с двумя полями, который усложняет множество соединений и подзапросов.Вы, вероятно, захотите дополнительный уникальный индекс для class_id и lesson_num, чтобы номер урока не использовался повторно для класса.Кроме того, эта таблица должна содержать term_num (или term_id), которому назначен конкретный урок для определенного класса.Это избавит вас от необходимости подсчитывать, какой термин используется в уроке, используя слишком сложную формулу MOD.Это было бы излишним.Просто сохраните номер термина с информацией об уроке, и вы сможете упорядочить термины по своему усмотрению.
Далее, поле id таблицы ответов должно быть уникальным с автоматическим приращением.Если это важно, вам также может потребоваться уникальный индекс для lesson_id и student_id (хотя это означает, что либо не повторяется, либо перезаписывается) .
Итак, теперь у меня есть:
- hl_classes (int id, int class_num, профессор, имя_класса, описание) PK: id, autoinc
- hl_classes_lessons (int id, int class_id, int lesson_num, int term_num, l_title, l_link, l_data)ПК: id, autoinc;Уникальный ключ: class_id, lesson_num
- hl_classes_answers (int id, int lesson_id, int student, ans, pct) PK: id, autoinc;Уникальный ключ: lesson_id, student
С этим я придумал:
select hC.id as next_class_id, hL.id as next_lesson_id, hC.class as next_class, hL.term_num as term_num, hC.class_num as next_class_num, hL.lesson_num AS next_lesson_num
from hl_classes hC
left join hl_classes_lessons hL on hL.class_id = hC.id
where hL.term_num = $TERM_NUM
and hL.id not in (
select hA.lesson_id
from hl_classes_answers hA
where student = $USER_ID
)
order by hC.class_num, hL.lesson_num
limit 1;
Это вернет вам либо одну строку, содержащую соответствующую информацию о следующем классе для этогостудент, учитывая этот термин, или все нули.Обратите внимание, что идентификаторы не для отображения, так как они могут быть любым старым числом.Вы бы отобразили поля _num.