Лучший запрос для объединений

0

Хорошо, поэтому у меня есть три таблицы типа

Студенты

Name        StudendId
----------------------
John            1
Jane            2
Bob             3
Betty           4

Класс

StudentId   TeacherId
----------------------
1            1
2            2
3            1
4            2
1            3
4            3

Учитель

Name          TeacherId
------------------------
Jim               1
Joan              2
Jill              3

Хорошо, поэтому я хочу найти учителя, который учит и Джона, и Боба.

До сих пор мой запрос:

 select distinct Teachers.Name from Teachers, 
   ((select Teachers.Name from Class, Students 
     where Students.StudendId = Class.StudentId and Students.Name = 'John') as tbl1
    join
   (select Class.TeacherId from Class, Students 
     where Students.StudendId = Class.StudentId and Students.Name = 'Bob') as tbl2
   on tbl1.TeacherId = tbl2.TeacherId) where Teachers.TeacherId = tbl1.TeacherId;

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

Спасибо, Vinh

Теги:
query-optimization

2 ответа

2
Лучший ответ

Использование:

  SELECT t.name
    FROM TEACHERS t
    JOIN CLASS c ON c.teacherid = t.teacherid
    JOIN STUDENTS s ON s.studentid = c.studentid
                   AND s.name IN ('John', 'Bob')
GROUP BY t.name
  HAVING COUNT(DISTINCT s.name) = 2

HAVING COUNT(DISTINCT s.name) должен равняться числу имен, указанных в предложении IN, поскольку IN означает, что имена могут быть John или Bob, в дополнение к учителям, чтобы иметь обоих учеников. DISTINCT изолирует от возможности дублирования имен (2x John и т.д.), Что было бы ложным положительным.

  • 0
    Таким образом, если вы делаете это программно для любого числа учащихся, вы передаете список имен учащихся в запрос, а предложение HAVING = количество элементов в списке. Правильно?
  • 0
    @djacobson: Да, это правильно.
Показать ещё 3 комментария
1

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

Select t.Name
From Teacher t
        inner join Class c on c.TeacherId = t.TeacherId
        inner join Students s1 on s1.StudentId=c.StudentId
        inner join Students s2 on s2.StudentId=c.StudentId 
Where s1.Name = 'Bob'
      and s2.Name = 'John'
Group By t.Name
  • 0
    Да извините, только что понял это и исправил.
  • 0
    +1 - намного лучше

Ещё вопросы

Сообщество Overcoder
Наверх
Меню