2014-09-13 2 views
0

Теперь есть две таблицы student (sid, name) и курс (cid, name), отношение которого много для многих. Итак, есть еще одна таблица student_course (sid, cid), в которой хранится информация о том, какие курсы были выбраны кем.Получить курсы, выбранные всеми учащимися

Как написать sql, который может получить курсы, выбранные всеми учениками?

+0

нормально никаких проблем братан, это не происходит – Skynet

ответ

2

Стандартное решение: использовать NOT EXISTS (... NOT EXISTS (...)) конструкцию:

  • найти все курсы, в которых учатся все студенты часть
  • == >> там не должен существовать студент, который не принять участие в этом курсе

SELECT * FROM course c 
WHERE NOT EXISTS (
     SELECT * from student s 
     WHERE NOT EXISTS (
       SELECT * from student_course cs 
       WHERE cs.sid = s.sid 
       AND cs.cid = c.cid 
       ) 
     ) 
     ; 

Этот запрос часто быстрее (данные индексов), соответствующий ему, чем count() == count() вариант. Причина этого: вам не нужно подсчитывать все (отдельные) записи; как только вы нашли один студента, который делает не принимать этот курс, вы можете пропустить этот курс из вашего списка подозреваемых. Также: ANTI-присоединяется часто можно использовать индексы [так может COUNT(), но до сих пор считать все в (различные) KeyValues ​​в индексе]

+0

мне нравится мой ответ. Тем не менее, я люблю тебя лучше. Он также работает намного лучше, когда пробегает мой же Fiddle. Так что проголосуйте – pinkfloydx33

1
Select c.cid, c.name 
From course c where 
(select count(1) from student) = (select count(1) from student_course sc where sc.cid = c.cid); 

See SQL Fiddle

Он находит все курсы, где подсчет записей для этого курса в таблице student_course соответствует количеству студентов

CID NAME 
1 Test Course1 
4 Test Course4