Как выбрать строки в отношении многих ко многим? (SQL) - PullRequest
1 голос
/ 31 октября 2019

У меня есть стол для студентов и стол для курсов. Они имеют много-много отношений между ними, и таблица StudentCourses является посредником. Теперь у меня есть список идентификаторов курсов, и я хочу выбрать студентов, которые следуют всем курсам в моем списке. Как ??

--CREATE TYPE CourseListType AS TABLE
--(
--  CourseID INT
--)

DECLARE
     @CourseList CourseListType

CREATE TABLE #Students
(
     ID INT
    ,Name CHAR(10)
)

CREATE TABLE #Courses
(
     ID INT
    ,Name CHAR(10)
)

CREATE TABLE #StudentCourses
(
     StudentID INT
    ,CourseID INT
)

INSERT INTO @CourseList (CourseID)
    VALUES
         (1) --English
        ,(2) --Math

INSERT INTO #Students (ID, Name)
VALUES
     (1, 'John')
    ,(2, 'Jane')
    ,(3, 'Donald')

INSERT INTO #Courses (ID, Name)
VALUES
     (1, 'English')
    ,(2, 'Math')
    ,(3, 'Geography')

INSERT INTO #StudentCourses (StudentID, CourseID)
VALUES
     (1, 1)
    ,(1, 2)
    ,(2, 1)
    ,(2, 2)
    ,(3, 1)
    ,(3, 3)

В этом примере я хочу, чтобы результатом были только Джон и Джейн, потому что у них обоих есть два курса в моем CourseList. Я не хочу Дональда, потому что у него есть только один из них.

Попробовал это СОЕДИНЕНИЕ, конструкцию, но это не исключает студентов, у которых есть только некоторые из моих желаемых курсов.

SELECT 
    * 
FROM 
    @CourseList CRL
    INNER JOIN #Courses CRS ON CRS.ID = CRL.CourseID
    INNER JOIN #StudentCourses STC ON STC.CourseID = CRS.ID
    INNER JOIN #Students STD ON STD.ID = STC.StudentID

1 Ответ

0 голосов
/ 31 октября 2019

Если вы хотите, чтобы студенты проходили все необходимые курсы, вы можете использовать агрегацию и having:

SELECT sc.StudentId 
FROM #StudentCourses sc JOIN
    @CourseList cl
    ON sc.CourseID = cl.id
GROUP BY sc.StudentId
HAVING COUNT(DISTINCT sc.CourseId) = (SELECT COUNT(*) FROM @DcourseList);

Если вам нужна дополнительная информация о студентах, вы можете присоединиться к таблице Students (илииспользуйте IN или аналогичную конструкцию).

Обратите внимание, что для этого нужна только таблица StudentCourses. У него совпадают идентификаторы. Нет необходимости объединяться в справочные таблицы.

...