Объединить несколько строк данных в одну строку - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть три таблицы, и я хочу объединить идентификаторы книг с читателями и версиями в одну строку.Читатели и версия должны быть объединены с ','.

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    

На данный момент яиспользуйте этот запрос

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

И я получаю такой результат:

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 

Но я хочу получить такой результат:

 BookId  Reader                 Version    
 --------------------------------------------
    1    James                  v1, v2
    2    Stephane, Michael      v1, v2, v3
    3    NULL      NULL    
    4    NULL      NULL 

Какой лучший способ сделатьЭто ?С CTE?или есть другой подход?Спасибо

1 Ответ

0 голосов
/ 24 сентября 2018

Вы можете использовать STUFF для генерации значений CSV.Ниже то, что я обычно использую.

    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;

Результат:

+----+--------------------+-------------+
| Id |       Reader       |   Version   |
+----+--------------------+-------------+
|  1 | James              | v1, v2      |
|  2 | Stephane, Michael  | v1, v2, v3  |
|  3 | NULL               | NULL        |
|  4 | NULL               | NULL        |
+----+--------------------+-------------+
...