问题
I have three tables and I want to merge book ids that have readers and versions into one rows. Readers and Version should be concatenated with ','.
Book
Id name description
----------------------
1 Book1 Book 1 Title
2 Book2 Book 2 Title
3 Book3 Book 3 Title
4 Book5 Book 5 Title
BookReader
BookId Name
----------------------
1 James
2 Stephane
2 Michael
BookVersion
BookId version
----------------------------------
1 v1
1 v2
2 v1
2 v2
2 v3
For now i use this query
select
b.id as BookId, r.name as Reader, v.version as Version
from
Book as b
left outer join
BookReader as r on r.bookId = b.id
left outer join
BookVersion as v on v.bookId = b.id
And I get this result :
BookId Reader Version
----------------------
1 James v1
1 James v2
2 Stephane v1
2 Stephane v2
2 Stephane V3
2 Michael v1
2 Michael v2
2 Michael V3
3 NULL NULL
4 NULL NULL
But I want a result like this:
BookId Reader Version
--------------------------------------------
1 James v1, v2
2 Stephane, Michael v1, v2, v3
3 NULL NULL
4 NULL NULL
What's the best way to do it ? With CTE ? or there's a another approach? Thanks
回答1:
You can use STUFF to generate csv values. Below is what I normally use.
CREATE TABLE #Book
(
Id INT ,
NAME VARCHAR(100) ,
Description VARCHAR(100)
);
CREATE TABLE #BookReader
(
BookId INT ,
Name VARCHAR(100)
);
CREATE TABLE #BookVersion
(
BookId INT ,
Version VARCHAR(10)
);
INSERT INTO #Book ( Id ,
NAME ,
Description )
VALUES ( 1 , -- Id - int
'Book1' , -- NAME - varchar(100)
'Book 1 Title' -- Description - varchar(100)
) ,
( 2 , -- Id - int
'Book2' , -- NAME - varchar(100)
'Book 2 Title' -- Description - varchar(100)
) ,
( 3 , -- Id - int
'Book3' , -- NAME - varchar(100)
'Book 3 Title' -- Description - varchar(100)
) ,
( 4 , -- Id - int
'Book5' , -- NAME - varchar(100)
'Book 5 Title' -- Description - varchar(100)
);
INSERT INTO #BookReader ( BookId ,
Name )
VALUES ( 1 , -- BookId - int
'James' -- Name - varchar(100)
) ,
( 2 , -- BookId - int
'Stephane' -- Name - varchar(100)
) ,
( 2 , -- BookId - int
'Michael' -- Name - varchar(100)
);
INSERT INTO #BookVersion ( BookId ,
Version )
VALUES ( 1 , -- BookId - int
'v1' -- Version - varchar(10)
) ,
( 1 , -- BookId - int
'v2' -- Version - varchar(10)
) ,
( 2 , -- BookId - int
'v1' -- Version - varchar(10)
) ,
( 2 , -- BookId - int
'v2' -- Version - varchar(10)
) ,
( 2 , -- BookId - int
'v3' -- Version - varchar(10)
);
SELECT b.Id ,
LTRIM(STUFF(( SELECT ', ' + br1.[Name] AS [text()]
FROM #BookReader br1
WHERE br1.BookId = b.Id
FOR XML PATH('')) ,
1 ,
1 ,
'')) AS Reader ,
LTRIM(STUFF(( SELECT ', ' + Version
FROM #BookVersion bv1
WHERE bv1.BookId = b.Id
FOR XML PATH('')) ,
1 ,
1 ,
'')) AS version
FROM #Book b;
DROP TABLE #Book;
DROP TABLE #BookReader;
DROP TABLE #BookVersion;
Result:
+----+--------------------+-------------+
| Id | Reader | Version |
+----+--------------------+-------------+
| 1 | James | v1, v2 |
| 2 | Stephane, Michael | v1, v2, v3 |
| 3 | NULL | NULL |
| 4 | NULL | NULL |
+----+--------------------+-------------+
来源:https://stackoverflow.com/questions/52470778/concatenate-multiple-data-rows-into-one-row