【问题标题】:SQL Server: Combine multiple rows into one with no overlap but new columnsSQL Server:将多行合并为一,没有重叠但新列
【发布时间】:2017-08-23 22:19:24
【问题描述】:

我有一个像这样的“详细信息”表:

    ID         |        BookID         |        Genre
    _____________________________________________________
    1          |         12            |         AB
    1          |         05            |         AC
    2          |         12            |         AB
    2          |         08            |         BB

有没有办法以这种格式组合行:

    ID  | BookID1 | Genre1  | BookID2 | Genre2
    _____________________________________________________
    1   | 12      | AB      | 05      |   AC
    2   | 12      | AB      | 08      |   BB

我需要以这种格式将各个列添加到存储过程中。

我通常很想包含一些代码或尝试,但我现在一无所知。

不是以下内容的重复: T-SQL dynamic pivot

我没有使用 tsql 的第一个区别

第二个不同是表格的结构不能应用于我的。

我的值不是将是列标题,而是它们将生成列,例如:

    ID  | BookID1 | Genre1  | BookID2 | Genre2  | BookID3 | Genre3  | BookID4 | Genre4
    1   | 05      | Horror  | 12      | Horror  | 03      | Drama   |         | 
    2   | 05      | Horror  | 15      | Advent  | 03      | Drama   | 112     | RomCom

第三个我无法掌握结构,因为我对数据透视表的了解为零

【问题讨论】:

标签: sql sql-server stored-procedures


【解决方案1】:

尝试动态 sql 查询

CREATE TABLE #BookGenreMapping
(
   Id int,
   BookId int,
   Genre varchar(20)
)

INSERT INTO #BookGenreMapping VALUES (1,12,'AB'),(1,05,'AC'),(2,12,'AB'),(2,08,'BC'),(2,09,'BCD')
DECLARE @HeaderAll nvarchar(max)
DECLARE @ColumnPivotBookId nvarchar(max)
DECLARE @ColumnPivotGenre nvarchar(max)

;WITH temp AS
(
   SELECT *, 
   CONCAT('BookID' ,row_number() OVER(PARTITION BY bgm.Id ORDER BY bgm.BookId)) AS BookGroupId,
   CONCAT('BookGroupGenre' ,row_number() OVER(PARTITION BY bgm.Id ORDER BY bgm.BookId)) AS BookGroupGenre
   FROM #BookGenreMapping bgm
),
temp1 AS 
(
   SELECT DISTINCT t.BookGroupId, t.BookGroupGenre FROM temp t
)
SELECT @HeaderAll = STUFF((SELECT CONCAT(',',t.BookGroupId, ',', t.BookGroupGenre) FROM temp1 t FOR XML PATH('')), 1,1,''),
     @ColumnPivotBookId =  STUFF((SELECT CONCAT(',',t.BookGroupId) FROM temp1 t FOR XML PATH('')), 1,1,''),
     @ColumnPivotGenre =  STUFF((SELECT CONCAT(',', t.BookGroupGenre) FROM temp1 t FOR XML PATH('')), 1,1,'')

--SELECT @HeaderAll, @ColumnPivotBookId, @ColumnPivotGenre


DECLARE @query nvarchar(max) = CONCAT(
      ';WITH temp AS
      (
         SELECT *, 
         CONCAT(''','BookID',''' ,row_number() OVER(PARTITION BY bgm.Id ORDER BY bgm.BookId)) AS BookGroupId,
         CONCAT(''','BookGroupGenre',''' ,row_number() OVER(PARTITION BY bgm.Id ORDER BY bgm.BookId)) AS BookGroupGenre
         FROM #BookGenreMapping bgm
      )
      SELECT pt1.Id, ',@HeaderAll,' FROM
      (
          SELECT Id, ',@ColumnPivotBookId,' FROM 
          (
            SELECT t.Id, t.BookId, t.BookGroupId FROM temp t
          ) src
          PIVOT
          (
            MIN(BookId) FOR BookGroupId IN (',@ColumnPivotBookId,')    
          ) pvt
       ) pt1
       INNER JOIN
       (
          SELECT Id, ',@ColumnPivotGenre,' FROM 
          (
            SELECT t.Id, t.Genre, t.BookGroupGenre FROM temp t
          ) src
          PIVOT
          (
            MIN(Genre) FOR BookGroupGenre IN (',@ColumnPivotGenre,')    
          ) pvt
       ) pt2 ON pt1.Id = pt2.Id'
       )

PRINT @query
exec(@query)


DROP TABLE #BookGenreMapping

【讨论】:

    【解决方案2】:

    对于所有与我的情况相似的人。

    下面的链接是一个巨大的帮助:

    https://community.spiceworks.com/topic/973727-sql-how-to-convert-multiple-rows-into-single-rows-with-more-columns

    【讨论】:

      猜你喜欢
      • 2012-05-27
      • 2011-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 2018-04-22
      相关资源
      最近更新 更多