То, что вы ищете, является типичным m:n
отношением.
У вас есть Студенты, у вас есть Курсы.Оба они существуют независимо.Теперь вы хотите запомнить, какой студент какой курс берет.Поэтому вам нужна таблица сопоставления между:
CREATE TABLE Student(ID INT NOT NULL CONSTRAINT PK_Student PRIMARY KEY
,FirstName NVARCHAR(200) NOT NULL
,LastName NVARCHAR(200) NOT NULL);
INSERT INTO Student(ID,FirstName,LastName)
VALUES(1,'Sonu','Jones')
,(2,'Janu','Smith')
,(3,'Sameer','Miller')
,(4,'Shri','Wilson');
CREATE TABLE Course(ID INT NOT NULL CONSTRAINT PK_Course PRIMARY KEY
,Title NVARCHAR(200) NOT NULL);
INSERT INTO Course(ID,Title)
VALUES(1,'JAVA')
,(2,'SQL')
,(3,'HTML')
,(4,'PHP');
CREATE TABLE CourseStudent(ID INT IDENTITY CONSTRAINT PK_CourseStudent PRIMARY KEY
,CourseID INT NOT NULL CONSTRAINT FK_CourseID FOREIGN KEY REFERENCES Course(ID)
,StudentID INT NOT NULL CONSTRAINT FK_StudentID FOREIGN KEY REFERENCES Student(ID));
INSERT INTO CourseStudent VALUES(1,1),(1,2),(1,3) --Course 1 is taken by 1,2,3
,(2,2),(2,3) --Course 2 is taken by 2 and 3
,(3,3),(3,4)
,(4,2),(4,1);
- это типичный select
, который вы использовали бы для получения сопоставленных данных
SELECT c.Title
,s.FirstName
FROM Course AS c
INNER JOIN CourseStudent AS cs ON c.ID=cs.CourseID
INNER JOIN Student AS s ON s.ID=cs.StudentID
- и это выбор, который вы использовали бы, чтобы получить участвующих студентов в виде сцепленной строки:
SELECT c.Title
,STUFF(
(
SELECT ', ' + s.FirstName
FROM CourseStudent AS cs
INNER JOIN Student AS s ON cs.StudentID=s.ID
WHERE cs.CourseID=c.ID
FOR XML PATH(''),TYPE
).value('.','nvarchar(max)'),1,2,''
) AS StudentName
FROM Course AS c;
Я использую довольно странный трюк с XML для достижения конкатенации сгруппированных строк.SQL-Server 2017+ представляет для этого STRING_AGG()
.