Верните идентификаторы, имена и фамилии всех студентов, которые взяли как ENG 101, так и ENG 102 (2 столбца, 11 строк) - PullRequest
0 голосов
/ 27 января 2020

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

select s01.StudentID, s01.StudFirstName, s01.StudLastName
from Students s01

join Student_Schedules as ss01
    on s01.StudentID = ss01.StudentID

join Classes as c01
    on ss01.ClassID = c01.ClassID

join Subjects as sbj01
    on c01.SubjectID = sbj01.SubjectID

--rejoins
join Students as s02
    on s01.StudentID = s02.StudentID

join Student_Schedules as ss02
    on ss01.StudentID = ss02.StudentID

join Classes as c02
    on c01.ClassID = c02.ClassID

join Subjects as sbj02
    on sbj01.SubjectID = sbj02.SubjectID


where sbj01.SubjectCode like 'ENG 101'
and sbj02.SubjectCode like 'ENG 102';

Ответы [ 3 ]

2 голосов
/ 27 января 2020

Если бы вы хотели, чтобы все студенты, которые изучали 3 предмета или более, использовали бы вы тройное соединение (или больше)? Это убийца производительности. Вместо всех этих двойных объединений, объедините один раз, фильтруйте и агрегируйте с условием в предложении having:

select s.StudentID, s.StudFirstName, s.StudLastName
from Students s
join Student_Schedules as ss on s.StudentID = ss.StudentID
join Classes as c on ss.ClassID = c.ClassID
join Subjects as sbj on c.SubjectID = sbj.SubjectID
where sbj.SubjectCode in ('ENG 101', 'ENG 102')
group by s.StudentID, s.StudFirstName, s.StudLastName
having count(distinct sbj.SubjectCode) = 2

Я считаю, что distinct на самом деле не требуется в count(), если нет дубликаты.

1 голос
/ 27 января 2020

Я думаю, что это то, что вы имеете в виду:

select s.StudentID, s.StudFirstName, s.StudLastName
from Students s
join Student_Schedules as ss01 on s.StudentID = ss01.StudentID
join Classes as c01 on ss01.ClassID = c01.ClassID
join Subjects as sbj01 on c01.SubjectID = sbj01.SubjectID
join Student_Schedules as ss02 on s.StudentID = ss02.StudentID
join Classes as c02 on ss02.ClassID = c02.ClassID
join Subjects as sbj02 on c02.SubjectID = sbj02.SubjectID
where sbj01.SubjectCode = 'ENG 101' and sbj02.SubjectCode = 'ENG 102';

Объяснение:

  • ваш запрос пытается найти ученика, который взял и 'ENG 101', и 'ENG 102' классы; для этого вы следуете двумя разными путями (Students > Student_Schedule > Subjects)

  • , но вы используете условия соединения, такие как ss01.StudentID = ss02.StudentID, которые заставляют оба пути быть тождественны; так что вы на самом деле в конечном итоге ищете Subject с кодом 'ENG 101' и 'ENG 102', что невозможно

Я установил условия соединения на то, что я думаю, что вы хочу.

Примечания:

  • вам не нужно вводить Students дважды
  • LIKE 'ENG 101' эквивалентно = 'ENG 101'
0 голосов
/ 27 января 2020

Лично я бы перестроил логи c, используя exists, поскольку именно так я и думал об этом.

  • Я бы использовал полное имя соединения, inner join для ясности.
  • Я бы полностью квалифицировал имена таблиц с именем схемы, например, dbo.
  • Я бы использовал = вместо like, поскольку вы не выполняете поиск по шаблону
    select s01.StudentID, s01.StudFirstName, s01.StudLastName
    from dbo.Students s01
    where exists (
      select 1
      from dbo.Student_Schedules as ss01
      inner join dbo.Classes as c01 on ss01.ClassID = c01.ClassID
      inner join dbo.Subjects as sbj01 on c01.SubjectID = sbj01.SubjectID
      where s01.StudendID = ss01.StudendID
      and sbj01.SubjectCode = 'ENG 101'
    )
    and exists (
      select 1
      from dbo.Student_Schedules as ss02
      inner join dbo.Classes as c02 on ss02.ClassID = c02.ClassID
      inner join dbo.Subjects as sbj02 on c02.SubjectID = sbj02.SubjectID
      where s01.StudendID = ss02.StudendID
      and sbj02.SubjectCode = 'ENG 102'
    )
...