SQL: присоединиться к более чем одному столу - PullRequest
0 голосов
/ 21 июня 2020

Напишите запрос sql, чтобы выбрать имена студентов, которые посетили все лекции профессора «ДЖОН», но не любую лекцию профессора «ДЖОЗЕФ».

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

select distinct s.studentname 
from Student s,Attendance a,Lecture l 
where s.StudentId=a.studid 
  and l.lecId = a.lectureid 
  and l.professor='JOHN' 
  and l.professor != 'JOSEPH';

Я делаю некоторую ошибку в приведенном выше запросе, но не могу ее идентифицировать.

вот структура таблицы

Таблица учеников

# StudentId, StudentName, Sex
'1', 'AMY', 'M'
'2', 'JACK', 'M'
'3', 'TONY', 'M'
'4', 'TARA', 'M'
'5', 'SARAH', 'F'
'6', 'TOM', 'F'

Таблица лекций

# LecId, Subject, Professor
1, MATH, JOHN
2, MATH, JOSEPH
3, PHY, MARK
4, PHY, MAX
5, PHY, JOHN
6, CHEM, JOHN
7, CHEM, JOSEPH
8, HISTORY, JOSEPH

Таблица посещаемости

# StudId, LectureId
'1', '1'
'1', '2'
'3', '1'
'2', '5'
'2', '6'
'3', '4'
'1', '6'
'4', '5'
'5', '1'
'5', '2'
'1', '3'
'1', '4'
'1', '5'
'1', '6'

Ответы [ 4 ]

1 голос
/ 21 июня 2020

Вам нужно просмотреть все строки, принадлежащие данному студенту, поэтому простое предложение where не может сделать то, что вы хотите. Вместо этого вы можете использовать агрегацию и фильтрацию с предложением having:

select s.studentname 
from student s
inner join attendance a on s.studentId = a.studid
inner join lecture l on l.lecId = a.lectureid 
group by s.studentId, s.studentname 
having max(l.professor= 'JOHN') = 1 and max(l.professor = 'JOSEPH') = 0

Если вы хотите, чтобы учителя добавляли все лекции Джона и ни одной лекции Джозефа, тогда:

select s.studentname 
from student s
inner join attendance a on s.studentId = a.studid
inner join lecture l on l.lecId = a.lectureid 
group by s.studentId, s.studentname 
having 
    sum(l.professor= 'JOHN') = (select count(*) from lecture where professor = 'JOHN')
    and max(l.professor = 'JOSEPH') = 0
0 голосов
/ 21 июня 2020

Если ваша версия MySQL поддерживает GROUP_CONCAT, вы можете попробовать следующий сценарий:

Демо здесь

SELECT S.StudentId,S.StudentName, GROUP_CONCAT(DISTINCT L.Professor)
FROM Attendance A
INNER JOIN Lecture L ON A.LectureId = L.LecId
INNER JOIN Student S ON A.StudId = S.StudentId
GROUP BY S.StudentId,S.StudentName
HAVING  GROUP_CONCAT(DISTINCT L.Professor) = 'JOHN'

Этот запрос выше вернет список студентов, которые только беру курс от «ДЖОНА». Больше никого.

Но если ваше требование изменилось, чтобы добавить больше профессоров в список, вы можете соответственно добавить имена профессоров при проверке предложения HAVING. Но для этого случая вам нужно применить соответствующий порядок.

0 голосов
/ 21 июня 2020

Я перефразировал соединение, которое вы сделали ... но, похоже, оно сработало.

Возвращает ли этот запрос набор данных, который вы ищете?

SELECT s.studentname, l.Subject, l.Professor
FROM Student s JOIN Attendance a
ON s.StudentId = a.StudId
JOIN Lecture l 
ON l.lecId = a.lectureid
WHERE l.professor='JOHN' 
  AND l.professor != 'JOSEPH';
0 голосов
/ 21 июня 2020

Попробуйте:

select * from Student st
where exists(select * from Lecture l
             join Attendance a
             on l.LecId = a.LectureId
             where l.Professor = 'John'
             and a.StudId = st.StudentId)
and exists(select * from Lecture l
               join Attendance a
               on l.LecId = a.LectureId
               where l.Professor = 'Joseph'
               and a.StudId = st.StudentId)
...