PIVOT/UNPIVOT 多于一列
Posted
技术标签:
【中文标题】PIVOT/UNPIVOT 多于一列【英文标题】:PIVOT/UNPIVOT more than one column 【发布时间】:2019-01-02 04:01:16 【问题描述】:有没有办法使用 SQL Pivot
/Unpivot
从表Original
生成下面Converted
下的输出?
【问题讨论】:
请显示您的代码尝试。 【参考方案1】:不,没有 PIVOT/UNPIVOT 的变体可以让您在“转换”输出中创建第一行,id
在一个列中,type
的值用于其他每一列。
这需要一些自定义选择来创建第一行,然后使用 UNION 和 UNPIVOT 来创建其余行。
由于没有执行聚合,我不知道您为什么要在 SQL 中执行此操作。我个人会在表示层这样做。
【讨论】:
【参考方案2】:您可以使用动态 sql 实现“转换”布局,但要注意这种方法的性能和安全问题。
此外,正如 Tab Alleman 在他的回答中所说,这显然是表示层的工作。
如果您仍想在 SQL Server 中执行此操作,这里有一个可能的解决方案:
CREATE TABLE [dbo].[Test] (
[id] int
,[type] varchar(50)
,NBR varchar(50)
,c1_pos int
,c1_neg int
,c2_pos int
,c2_neg int )
INSERT INTO [dbo].[Test]
values
(8375, 'Type #1', 'P #1', 1, 0, 0, 0)
,(8375, 'Type #2', 'P #2', 0, 1, 0, 0)
,(8375, 'Type #3', 'P #1', 0, 1, 0, 0)
,(8375, 'Type #4', 'P #1', 1, 0, 0, 0)
,(8375, 'Type #5', 'P #1', 0, 0, 0, 0)
--this variable holds the value that will become the header of the first column
declare @first_column_header nvarchar(10)
--this variable holds all the dates that will become column names
declare @headers nvarchar(max)=''
--this variable contains the TSQL dinamically generated
declare @sql nvarchar(max)=''
SELECT @first_column_header = max(id) FROM [dbo].[Test] group by [id]
select @headers = @headers + ', ' + QUOTENAME([type]) from [dbo].[Test]
set @headers = RIGHT(@headers, len(@headers) - 2)
set @sql = @sql + 'select piv.col as ' + QUOTENAME(@first_column_header) + ', ' + @headers + ' '
set @sql = @sql + 'from '
set @sql = @sql + '( '
set @sql = @sql + ' select [type], col, val, ord '
set @sql = @sql + ' from [dbo].[Test] '
set @sql = @sql + ' CROSS APPLY ('
set @sql = @sql + ' VALUES (''NBR'' , cast(NBR as varchar(10)) , 1), '
set @sql = @sql + ' (''c1_pos'' , cast(c1_pos as varchar(10)) , 2), '
set @sql = @sql + ' (''c1_neg'' , cast(c1_neg as varchar(10)) , 3), '
set @sql = @sql + ' (''c2_pos'' , cast(c2_pos as varchar(10)) , 4), '
set @sql = @sql + ' (''c2_neg'' , cast(c2_neg as varchar(10)) , 5) '
set @sql = @sql + ' )CS (col, val, ord) '
set @sql = @sql + ') src '
set @sql = @sql + 'pivot ( max(val) for [type] in (' + @headers + ') ) piv '
set @sql = @sql + 'order by ord'
exec(@sql)
结果:
【讨论】:
以上是关于PIVOT/UNPIVOT 多于一列的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server 2008 中的 PIVOT / UNPIVOT
将矩阵转换为 3 列表('reverse pivot'、'unpivot'、'flatten'、'normalize')
将矩阵转换为 3 列表('reverse pivot'、'unpivot'、'flatten'、'normalize')