много ко многим с общим, где состояние

0
+------+--------+---------+
| 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

  • 0
    Как вы выполняете этот запрос? Прямо из MySQL? Или что-то другое?
Теги:
many-to-many

3 ответа

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

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

 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
    я не могу использовать, имея счет = 2, так как идентификатор учителя "в", и это может быть от 1 до 10 идентификаторов учителя
  • 0
    @LeeGary dbfiddle.uk/… вам не нужен этот результат
Показать ещё 6 комментариев
2

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

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

Изображение 174551

демонстрация

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

SELECT studentId
FROM teacher_students
WHERE teacherId IN (...)      -- some_num of teachers
GROUP BY studentId
HAVING COUNT(DISTINCT teacherId) = some_num;
  • 0
    так же, как ответ выше ... число учителей может использоваться как предикат, так как оно динамическое, оно может быть teacherId in (1,2,3,4)
  • 0
    Может быть, вы должны сказать нам, как или откуда вы будете выполнять этот запрос. Если вы используете утверждение, то вам необходимо параметризовать идентификаторы учителей и количество учителей.
0

Вы можете также использовать 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
             );

Ещё вопросы

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