Вложенный список в одном запросе в MySQL - PullRequest
0 голосов
/ 25 октября 2019

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

Вот мои таблицы:

Table PROFESSOR (id, name)
Table LECTURE (id, name, professorID, offeredThisYear) ... offeredThisYear is 1 or 0
Table STUDENT (id, name, inState) ... inState = 1 or 0 
Table LECTURE-STUDENT (lectureID, studentID)
  • НекоторыеЛекции предлагаются в этом году, некоторые или нет
  • Некоторые СТУДЕНТЫ являются государственными, другие или нет

Запрос Я пытаюсь написать:

ДляID ПРОФЕССОРА = 1, я хочу получить список всех ЛЕКЦИЙ, которые он / она преподает в этом году (offerThisYear = 1), и список только учеников штата (inState = 1), зарегистрированных в классе. Если у какой-либо ЛЕКЦИИ нет СТУДЕНТА, я хочу, чтобы она все еще была в списке.


Мои запросы:

SELECT * FROM lectures 
WHERE professorid = 2
AND offeredThisYear = 1
ORDER BY RAND()

Возвращает

Lecture 15=Law
Lecture 7=Philosophy
Lecture 17=Mathematics
Lecture 13=German

Теперь для каждоголекция, я хочу список студентов из других штатов, например:

Lecture 15=Law (Joshua, Patricia)
Lecture 7=Philosophy (Patricia, Joshua, Mary, Joseph, Sandra)
Lecture 17=Mathematics (Jessica)
Lecture 13=German ()

*** Примечание: никто не изучает немецкий, но он все еще указан, потому что профессор 2 преподает немецкий в этом году

Я не знаюЯ не хочу делать отдельный запрос для каждой лекции, например:

SELECT GROUP_CONCAT(DISTINCT p.name, ' ' ORDER BY RAND() SEPARATOR ', ') 
FROM students p, lectures_students q
WHERE q.lectureid = 17 
AND p.id = q.studentid
AND p.instate = 1

Как мне получить этот вложенный список одним запросом?

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

Большое спасибо за вашу помощь. Я программист-любитель, но это выходит за рамки моей компетенции.

Ответы [ 3 ]

0 голосов
/ 26 октября 2019

Я не верю, что вы вполне определились с тем, каковы ваши настоящие имена таблиц (т.е. вы не были последовательны), поэтому вам придется извинить меня, если я не совсем правильно понял.

В следующем SQL-коде используется принятый в настоящее время синтаксис JOIN:

SELECT l.name, GROUP_CONCAT(p.name ORDER BY s.name ASC SEPARATOR ', ') 
FROM LECTURE l LEFT JOIN LECTURE_STUDENT ls on l.id = ls.professorID
LEFT JOIN STUDENT s ON ls.studentID = s.id
WHERE s.inState = 1
GROUP BY l.name

Примечание. Я использовал l, s и ls в качестве альтернатив для таблиц более логичным образом.

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

0 голосов
/ 26 октября 2019

Спасибо обоим респондентам. Я объединился, чтобы получить правильный результат. Этот код работает.

SELECT 
    l.id,
    l.name, 
    GROUP_CONCAT(s.name ORDER BY RAND() SEPARATOR ', ') 
FROM lectures l
LEFT JOIN lectures_students ls ON ls.lectureid = l.id
LEFT JOIN students s ON s.id = ls.studentId AND s.inState = 1
WHERE l.professorid = 2 AND l.offeredthisyear = 1
GROUP BY l.id, l.name
ORDER BY RAND()
0 голосов
/ 26 октября 2019

Я думаю, что вы хотите left join с и агрегации. Вы можете начать присоединение с lectures, а затем следовать отношениям с lecture_students, затем students;Фильтр для 'inState' студентов должен быть помещен в предложение on left join. Затем вы можете агрегировать по лекциям и перечислять имена всех студентов, которые посещали каждую лекцию.

select 
    l.id,
    l.name, 
    group_concat(s.name order by s.id) student_names
from lectures l
left join lecture_student ls on ls.professorId = l.professorId
left join student s on s.id = ls.studentId and s.inState = 1
where l.professorid = 2 and l.offeredthisyear = 1
group by l.id, l.name
...