Помощь с объединением SQL в сочетании с большим количеством подзапросов

У меня ограниченный опыт работы с соединениями, и эта головоломка поставила меня в тупик.

Вот соответствующие таблицы из моей базы данных mysql:

  • Студенческий стол
  • Таблица разделов, описывающая разделы данного курса
  • Таблица сопоставления, которая создает отношения «многие ко многим» между разделами и учащимися.
  • Таблица экзаменов с описанием экзаменов
  • Таблица сопоставления «многие ко многим» между экзаменами и разделами
  • Таблица exam_schedules, описывающая дни, в которые можно сдавать экзамены. Между экзаменами и расписанием экзаменов существует отношение "один ко многим".

Моя цель: найти всех учащихся, зарегистрированных в секциях, экзамены которых запланированы на определенную дату. Также получите информацию о расписании экзаменов для каждого теста, который студент должен пройти в указанную дату. Желательно иметь строку в результирующем наборе для каждой пары student‹->exam_schedule.

У меня есть запрос, который выполняет первую половину моей цели (у него много подзапросов):

SELECT * FROM `students` WHERE `id` IN
    (SELECT `student_id` FROM `sections_students` WHERE `section_id` IN
        (SELECT `section_id` FROM `sections_exams` WHERE `exam_id` IN
            (SELECT `exam_id` FROM `exam_schedules` WHERE `date` = DATE('$date') AND `exam_id` IN
                (SELECT `id` FROM `exams` WHERE `isAutoSignup` = 1))))

Чего я не могу понять, так это того, как включить в это соединение, чтобы выполнить вторую половину моей цели. Каждая моя попытка приводила к синтаксической ошибке. Пожалуйста, может ли кто-нибудь указать мне в правильном направлении? Заранее спасибо!


person Ryan Ballantyne    schedule 24.03.2011    source источник


Ответы (2)


вы можете сделать все это с соединениями и, таким образом, получить exam_schedules таким образом:

SELECT s.*, es.*
  FROM students s
JOIN sections_students ss on s.id          = ss.student_id
JOIN sections_exams    se on se.section_id = ss.section_id
JOIN exam_schedules    es on es.exam_id    = se.exam_id and date = DATE('$date')
JOIN exams             e  on e.id          = es.exam_id and isAutoSignup = 1
person manji    schedule 24.03.2011

Вот снимок:

SELECT S.Student_name, E.Exam_name, ES.date
FROM students S
LEFT OUTER JOIN SECTIONS_STUDENTS SS
  ON SS.student_id = S.stuent_id
LEFT OUTER JOIN SECTIONS_EXAMS SE
  ON SE.section_id = SS.section_id
LEFT OUTER JOIN  EXAMS E
  ON E.exam_id = SE.exam_id
LEFT OUTER JOIN EXAM_SCHEDULES ES
  ON ES.exam_id =E.exam_id
WHERE 1=1
  AND E.isAutoSignup = 1
  AND ES.Date = DATE('$date')

Соединения подобны написанию ваших мыслей.

Я хочу студентов, и я хочу студентов в секциях, и я хочу экзамены для секций, и я хочу, чтобы расписание экзаменов отфильтровывалось по расписанию экзаменов, и экзамены таким образом...

person Daniel Williams    schedule 24.03.2011
comment
Просто я всегда так присоединяюсь. Если вы напишете: SELECT * FROM a,b,c,d,e WHERE ‹некоторые критерии›, скорее всего, вы случайно сделаете ложное перекрестное соединение. Но почему ВНЕШНИЙ против ВНУТРЕННЕГО? Это могло пойти в любом случае. Я бы хотел видеть студентов, у которых нет экзаменов. - person Daniel Williams; 25.03.2011
comment
Да, но ОП хотела студентов, у которых сдаются экзамены. В любом случае ваш запрос фактически эквивалентен использованию внутренних соединений из-за неуместных предикатов в E.isAutoSignup и ES.Date (они будут NULL для студентов без экзаменов). - person Ronnis; 26.03.2011