У вас хороший дизайн стола - вы сможете делать все, что захотите, когда будете хранить информацию таким образом.
Поскольку у вас есть взаимные отношения, ваши первоначальные отчеты будут иметь избыточность, если вы не предпримете шаги для их удаления. Под этим я подразумеваю, что если Фред встречает Мэри на встрече № 1, то Мэри встречает Фреда на той же встрече. Итак, первое решение, приведенное ниже, перечисляет всех дважды, но это полезно, если вы хотите, чтобы кто-то мог найти кого-то в вашем списке людей и перечислить, с кем они встречались:
SELECT distinct p1.name, 'met', p2.name, 'at', a1.meeting_id
FROM people as p1
JOIN attend as a1 on a1.people_id = p1.id
JOIN attend as a2 on a2.meeting_id = a1.meeting_id
JOIN people as p2 on p2.id = a2.people_id
where p1.id <> p2.id
order by a1.meeting_id;
+------+-----+------+----+------------+
| name | met | name | at | meeting_id |
+------+-----+------+----+------------+
| Mary | met | Fred | at | 1 |
| Fred | met | Mary | at | 1 |
| Eric | met | Mary | at | 2 |
| Mary | met | Eric | at | 2 |
+------+-----+------+----+------------+
Вы понимаете, что я имею в виду, когда перечисляю всех дважды. Если вы сортируете по p1.name или p2.name, вы сгруппируете людей, чтобы все, кого встретила «Мэри», были вместе в списке.
Но вы можете делать другие вещи, в зависимости от того, как программа, использующая ваши запросы, будет работать.
SELECT p.name, (SELECT group_concat(name)
FROM people as p1
JOIN attend as a1 on a1.people_id = p1.id
JOIN attend as a2 on a2.meeting_id = a1.meeting_id
WHERE a2.people_id = p.id
AND p.id <> p1.id)
FROM people as p
ORDER by p.name;
+------+-----------+
| name | People |
+------+-----------+
| Eric | Mary |
| Fred | Mary |
| Mary | Fred,Eric |
+------+-----------+
Это менее эффективно (что может иметь или не иметь значения для вас), но вы получаете список для каждого человека, с кем они встречались. Вы можете расширить этот запрос, чтобы перечислить собрание (я), на котором они встречались, и т. Д.