Как подсчитать результаты MySQL в отношении «имеет много сквозных»

Существует довольно хорошая статья о том, как фильтровать результаты в отношении «имеет много»: Как фильтровать результаты SQL в отношении has-many-through

Я просто ищу решение для результата COUNT, а не показываю их все.

student {
    id
    name
}
club {
    id
    name
}
student_club {
    student_id
    club_id
}

Сколько учащихся в CLUB1 и& CLUB2?

EDIT: Было бы здорово использовать метод "Martin 2" по ссылке ниже:

SELECT s.stud_id, s.name
FROM   student s
JOIN   student_club sc USING (stud_id)
WHERE  sc.club_id IN (30, 50)
GROUP  BY 1,2
HAVING COUNT(*) > 1;

Просто добавить что-то к результатам COUNT.


person Community    schedule 13.03.2013    source источник


Ответы (2)


В запросе используются псевдонимы таблиц для таблиц student_club и club. Это позволяет возвращать строки только для студентов, состоящих в обоих клубах. Затем использование COUNT позволяет вернуть количество студентов:

SELECT COUNT(*) AS nb
FROM student s, student_club sc1, club c1, student_club sc2, club c2
WHERE s.id=sc1.student_id AND sc1.club_id=c1.id AND c1.name="CLUB1"
AND s.id=sc2.student_id AND sc2.club_id=c2.id AND c2.name="CLUB2"

Если вы действительно хотите использовать запрос «Мартин 2», вы можете подсчитать количество записей следующим образом:

SELECT COUNT(*) AS nb
FROM (
    SELECT s.stud_id, s.name
    FROM   student s
    JOIN   student_club sc USING (stud_id)
    WHERE  sc.club_id IN (30, 50)
    GROUP  BY 1,2
    HAVING COUNT(*) > 1
) tmp;
person Jocelyn    schedule 13.03.2013
comment
CLUB1 и CLUB2 — это просто примеры. их может быть 3 или больше и больше. было бы здорово использовать метод Мартина 2 и подсчитывать результаты. - person ; 13.03.2013
comment
Пожалуйста, не меняйте свой вопрос после того, как на него ответили! Ваш текущий вопрос: сколько студентов в CLUB1 и& CLUB2?, и мой ответ решает этот вопрос. - person Jocelyn; 13.03.2013
comment
Извините, если я не правильно объяснил, но для меня это не решение. - person ; 13.03.2013

Вероятно, самый простой, чистый и быстрый всего для двух студентов:

SELECT count(*) AS ct
FROM   student_club x
JOIN   student_club y USING (stud_id)
WHERE  x.club_id = 30
AND    y.club_id = 50;

Вам вообще не нужно присоединяться к таблице student для этого — как только вы узнаете список интересующих вас stud_id.

Для любого количества студентов более удобен запрос Мартина. Вы можете упростить аналогичным образом:

SELECT count(*) AS ct
FROM (
   SELECT stud_id
   FROM   student_club
   WHERE  club_id IN (30, 50)
   GROUP  BY 1
   HAVING count(*) = 2 -- adapt to number of items in list
   ) x;

Конечно, требуется, чтобы (stud_id, club_id) был уникальным, и чтобы элементы списка также были уникальными.

person Erwin Brandstetter    schedule 13.03.2013
comment
Большое спасибо. это действительно упрощает. - person ; 14.03.2013
comment
Можете ли вы объяснить, что означает x в конце запроса? - person ; 14.03.2013
comment
@IkaPkhakadze: это сокращение от AS x и псевдоним подзапроса. Каждому подзапросу в списке FROM необходимо имя в SQL. - person Erwin Brandstetter; 14.03.2013