SQL将具有不同值的一列转换为多个列

时间:2017-05-17 12:36:33

标签: sql sql-server

我正在使用SQL Server而且我不知道如何处理这个问题。 我有一个表格,其中有5.5M的记录,格式如下:

Device        Time             ValueID   Value   Voltage
------------------------------------------------------------
1   2014-03-08 22:50:00      AH1      90,0    90,000"

1   2014-03-08 22:50:00      AT1      5,5     5,500"

1   2014-03-08 22:50:00      PP1      0,0     0,000"

1   2014-03-08 22:50:00      WS1      0,0     0,000"

1   2014-03-08 22:50:00      WD1      270,0   270,000"

1   2014-03-08 22:50:00      SR1      0,0     0,000"

1   2014-03-08 23:49:00      ST1      8,288   2,993"

列ValueID有13种不同的数据类型,列Value包含数据类型的度量。

我需要创建一个包含以下格式的表:

Device Time ValueID(AH1) ValueID(AT1) ValueID(PP1) etc...
------------------------------------------------------------
  1    xxxx   Value         Value          Value  

我试图在一个带有case语句的新表中使用INSERT,但它不起作用,¿任何不同的方法? ¿有什么线索吗? 感谢

2 个答案:

答案 0 :(得分:3)

您可以使用以下角色:

select Device, [Time], [AH1] as [Value(AH1)], [AT1] as [Value(AT1)]... from (
    select Device, [Time], ValueId, [Value] from Yourtable )
pivot (max([value]) for valueId in ([AH1],[AT1]...)) p

您可以按如下方式生成动态列:

declare @cols varchar(max)
declare @fromcols varchar(max)
declare @query varchar(max)

select @cols = stuff((select ','+QuoteName(valueid) from #yourdevice group by valueid for xml path('')),1,1,'')
select @fromcols = stuff((select ','+QuoteName(valueid)+' as [Value('+ Valueid + ')]' from #yourdevice group by valueid for xml path('')),1,1,'')
--[AH1] as [Value(AH1)], [AT1] as [Value(AT1)]...

SET @query = 'select Device, [Time], ' + @fromcols + ' from ( ' + ' select Device, [Time], ValueId, [Value] from Yourtable ) a ' 
SET @Query = @query + ' pivot (max([value]) for valueId in (' + @cols + ')) p '

select @query --Execute below by uncommenting after checking the query
--exec sp_execute @query

答案 1 :(得分:2)

我们可以使用动态数据透视

来实现结果
IF OBJECT_ID('Tempdb..#temp') IS NOT NULL
Drop Table #temp

;WITH cte(Device,Time,ValueID,Value,Voltage)
AS
(
SELECT 1,'2014-03-08 22:50:00' ,'AH1', '90,0' ,  '90,000'   Union all
SELECT 1,'2014-03-08 22:50:00' ,'AT1', '5,5'  ,  '5,500'    Union all
SELECT 1,'2014-03-08 22:50:00' ,'PP1', '0,0'  ,  '0,000'    Union all
SELECT 1,'2014-03-08 22:50:00' ,'WS1', '0,0'  ,  '0,000'    Union all
SELECT 1,'2014-03-08 22:50:00' ,'WD1', '270,0',  '270,000'  Union all
SELECT 1,'2014-03-08 22:50:00' ,'SR1', '0,0'  ,  '0,000'    Union all
SELECT 1,'2014-03-08 23:49:00' ,'ST1', '8,288',  '2,993'  
)
SELECT * INTO #TEMP FROM CTE

Declare @Col nvarchar(max),
         @Sql nvarchar(max),
         @dynamicCol nvarchar(max)

SELECT @Col=STUFF((SELECT ', '+ ValueID 
From  #temp For XML PATH ('')),1,1,'')

;With cte
AS
(
SELECT STUFF((SELECT DISTINCT ', '+  ValueID + ' AS '+QUOTENAME(' ValueID ('+ValueID+')')
From  #temp For XML PATH ('')),1,1,'') AS DynamicColumnames
)
SELECT @dynamicCol= DynamicColumnames from cte

SET @Sql='
SELECT Device,Time,'+ @dynamicCol +' From
(
SELECT Device,Time,ValueID,Value From
#temp
)AS Src
PIVOT 
(
MAX(Value) For ValueID IN ('+@Col+')
)
AS Pvt'

Print @Sql

EXEC(@Sql)