【问题标题】:TSQL - Dynamic column header creation based column values (Pivot/Unpivot)TSQL - 基于列值的动态列标题创建(Pivot/Unpivot)
【发布时间】:2023-03-27 22:13:01
【问题描述】:

我必须处理下面的表结构才能将其转换为如下图中第二个表的视图:

由于“Var_Columns”列可以包含超过一百个不同的值,我想要一些动态语句,它会使用这些值来创建具有相应列标题的列标题价值观。

理想情况下,月份名称应采用“2016-01-01”等格式,以此类推。

我希望我能提供一些试错代码,但我已经一开始就卡住了。 因此我创建了一个SQL Fiddle,您可以看看。

希望有人知道如何解决这个问题。

谢谢,

丹尼尔

【问题讨论】:

  • 您的示例数据似乎与所需的输出不匹配。您必须首先取消透视,以便将数据规范化为行,然后进行动态透视以将其转回您想要的列。
  • 这里是一个如何取消透视然后旋转数据的示例。动态Var_Columns 部分应该很容易做到。为此,您需要将列命名为 February 而不是 Febuary sqlfiddle.com/#!6/95c35/2
  • 非常感谢您的示例。是否可以在动态创建的列标题周围放置“[]”?因为有些以 % 等字符开头或结尾。谢谢。

标签: sql-server tsql pivot transpose unpivot


【解决方案1】:

这是我使用动态 sql 派生列名的解决方案。

创建测试数据集:

CREATE TABLE input
    (
    [ID] int NOT NULL,
    [Version] [smallint] NOT NULL,
    [RowNo] [int] NOT NULL,
    [Dept] [nvarchar](max) NULL,
    [Info] [nvarchar](max) NULL,
    [Year] [nvarchar](max) NULL,
    [Var_Columns] [nvarchar](max) NULL,
    [January] [nvarchar](max) NULL,
    [Febuary] [nvarchar](max) NULL,
    [March] [nvarchar](max) NULL,
    [April] [nvarchar](max) NULL,
    [May] [nvarchar](max) NULL,
    [June] [nvarchar](max) NULL,
    [July] [nvarchar](max) NULL,
    [August] [nvarchar](max) NULL,
    [September] [nvarchar](max) NULL,
    [October] [nvarchar](max) NULL,
    [November] [nvarchar](max) NULL,
    [December] [nvarchar](max) NULL,
    )
;

INSERT INTO input
    ([ID], [Version], [RowNo],[Dept], [Info],[Year],[Var_Columns],[January],[Febuary], [March],[April],[May],[June],[July]
     ,[August],  [September] ,[October],[November],[December]
    )
VALUES
(1,2,1,'DeptA','Sheet','2016','varCol1','1','2','3','4','5','6','7','8','9','10','11','12'),
(1,2,2,'DeptA','Sheet','2016','varCol2','11','22','33','44','55','66','77','88','99','100','110','120'),
(1,2,3,'DeptA','Sheet','2016','varCol3','111','222','333','444','555','666','777','888','999','101','111','122'),
(2,2,1,'DeptB','Sheet','2016','varCol1','10','20','30','40','50','60','70','80','9','10','11','12')
;

实际解决方案:

--Create a variable to hold the column names for the unpivot
DECLARE @col VARCHAR(MAX)  = '';

-- insert the distinct Var_column entries into a temp table
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
    DROP TABLE #temp; 
SELECT DISTINCT [Var_Columns] INTO #temp
FROM input

--Assign the distinct Var_column entries in the temp table to the variable @col
SELECT   @col +=  QUOTENAME([Var_Columns])+',' from #temp;

--generate the dynamic query
DECLARE @sql varchar(max) = ''

SELECT  @sql = '

;WITH CTE AS (
 SELECT * 
FROM 
   (SELECT [ID], [Version], [Dept], [Info],[Year],[Var_Columns],[January],[Febuary], [March],[April],[May],[June],[July],[August],[September],[October],[November],[December]
   FROM input) p
UNPIVOT
   ([Values] FOR [Month] IN 
      ([January],[Febuary], [March],[April],[May],[June],[July],[August],[September],[October],[November],[December])
)AS unpvt)

SELECT [ID], [Version], [Dept], [Info],[Year],[Month], 
'+SUBSTRING(@col,1,LEN(@col)-1)+'
FROM
(SELECT *
    FROM CTE) AS SourceTable
PIVOT
(
MAX([Values])
FOR Var_Columns IN ('+SUBSTRING(@col,1,LEN(@col)-1)+')
) AS PivotTable;

; '

-- prin the query and then execute.
print (@sql)
EXECUTE (@sql)

GO

结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    • 2018-11-08
    • 2019-05-09
    • 1970-01-01
    • 2018-12-26
    • 2013-11-04
    相关资源
    最近更新 更多