много ко многим с общим, где состояние - PullRequest
0 голосов
/ 14 сентября 2018
+------+--------+---------+
| id   | teacher|student  |
+-------+-------+---------+
| 1    | 1      |1        |
| 2    | 3      |3        |
| 3    | 3      |4        |
| 4    | 3      |5        |
| 5    | 3      |6        |
| 6    | 4      |5        |
| 7    | 4      |6        |
+-------+-------+---------+

Это таблица связи «многие ко многим», как мне запросить список учеников, у которых у них есть общий учитель, например 3 и 4?

Я ожидаю, что смогу получить учеников 5 и 6, так как они оба "делят" одного и того же учителя?

что у меня сейчас есть

SELECT ts.studentId, ts.teacherId FROM teacher_students ts group by ts.studentId, ts.teacherId having ts.teacherId in (3,4);

Но я получаю ученика 3,4,5,6 вместо 5,6

Ответы [ 3 ]

0 голосов
/ 14 сентября 2018

использование условного аггрегайтона

 select studentId from teacher_students t
 where t.teacherId in (3,4)
 group by t.studentId
 having count(distinct t.teacherId )=2

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=70b3b2de9695f2f567afeaee7ec37bda

     studentId
       5
       6
0 голосов
/ 14 сентября 2018

Вы также можете использовать предложение where с exists:

SELECT ts.*
FROM teacher_students ts
WHERE teacherId IN (3,4) AND
      EXISTS (SELECT 1 
              FROM teacher_students ts1 
              WHERE ts.studentId = ts1.studentId AND ts.teacherId <> ts1.teacherId
             );
0 голосов
/ 14 сентября 2018

Вот один канонический способ сделать это:

SELECT studentId
FROM teacher_students
WHERE teacherId IN (3, 4)
GROUP BY studentId
HAVING MIN(teacherId) <> MAX(teacherId);

enter image description here

Демо

Одним из преимуществ вышеуказанного запроса является то, что он дружествен к индексу.В целом, если вы хотите, чтобы у учеников было три или более обычных преподавателя, вы могли бы использовать это:

SELECT studentId
FROM teacher_students
WHERE teacherId IN (...)      -- some_num of teachers
GROUP BY studentId
HAVING COUNT(DISTINCT teacherId) = some_num;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...