Reputation: 39
I have these 3 tables as below.
Table: Student
-------------
| ID | Name|
+-----+-----+
| S01 |Alex |
| S02 |Sam |
| S03 |May |
-------------
Table: Book
--------------
| ID | Name |
+-----+------+
| B01 |BookA |
| B02 |BookB |
| B03 |BookC |
--------------
Table:StudentBooks
--------------
| SID| BID |
+-----+------+
| S01 |B01 |
| S02 |B02 |
| S01 |B03 |
| S02 |B03 |
--------------
Here is the output I want to get.
-----------------------
| Name | Book |
+-------+-------------+
| Alex |BookA, Book C|
| Sam |BookB, Book C|
| May | |
-----------------------
I tried with the following code, but it seems not able to get the correct book name based on the student name. My current output is that all the books are shown in every row, including student named 'May' which not allocated with any books.
SELECT s.Name AS Name,
STUFF((SELECT ',' + b.Name
FROM StudentBook sb
JOIN Student s ON s.ID = sb.SID
JOIN Book b ON b.ID = sb.BID
WHERE s.Name = s.Name
FOR XML PATH('')),1,1,'') AS Book
FROM StudentBooks sb
JOIN Book b ON b.ID = sb.BID
JOIN Student s ON s.ID = sb.SID;
Upvotes: 0
Views: 381
Reputation: 50173
Your inner & outer references are not matching. You are referencing student name to book :
SELECT s.Name AS Name,
STUFF((SELECT ',' + b.Name
FROM StudentBook sb JOIN
Book b
ON b.ID = sb.BID
WHERE sb.sid = s.id
FOR XML PATH('')
), 1, 1, ''
) AS Book
FROM Student s;
Upvotes: 1
Reputation: 7
STRING_AGG will also solve the problem
SELECT S.[Name],
STRING_AGG(B.[Name], ', ') AS Books
FROM StudentBooks AS SB WITH(NOLOCK)
INNER JOIN Student AS S WITH(NOLOCK) ON S.ID = SB.SID
INNER JOIN Book AS B WITH(NOLOCK) ON B.ID = SB.BID
GROUP BY S.[Name]
Upvotes: 0