如何在SQL Server中将行值设置为列?

时间:2017-10-30 11:13:14

标签: sql-server tsql pivot

我有一张表tblTags(日期,Tagindex,价值)

表中的值为:

Date            Tagindex    Value
---------------------------------
2017-10-21         0          21
2017-10-21         1         212
2017-10-21         2          23
2017-10-21         0          34
2017-10-21         1          52
2017-10-21         2          65

我希望结果为:

Date            0    1     2
-------------------------------
2017-10-21      21   212   23
2017-10-21      34    52   65

为此,我编写了以下查询

select * 
from
    (SELECT a.Date, a.Tagindex,a.value
     FROM tblTag a) as p
pivot 
    (max(value)
        for Tagindex in ( [tblTag])
    ) as pvt

但是我得到了这些错误:

  

Msg 8114,Level 16,State 1,Line 10
  将数据类型nvarchar转换为int时出错。

     

Msg 473,Level 16,State 1,Line 10
  PIVOT运算符中提供了错误的值“tblTag”。

如何解决这个问题。

2 个答案:

答案 0 :(得分:1)

试试这个:

DECLARE @tblTag TABLE
(
    [Date] DATE
   ,[TagIndex] TINYINT
   ,[Value] INT
);

INSERT INTO @tblTag ([Date], [TagIndex], [Value])
VALUES ('2017-10-21', 0, 21)
      ,('2017-10-21', 1, 212)
      ,('2017-10-21', 2, 23)
      ,('2017-10-22', 0, 34)
      ,('2017-10-22', 1, 52)
      ,('2017-10-22', 2, 65);

SELECT *
FROM @tblTag
PIVOT
(
    MAX([value]) FOR [Tagindex] IN ([0], [1], [2]) 
) PVT;

你需要准确地说which are the PIVOT columns。如果您要为TagIndex设置不同的值并且无法对它们进行硬编码,则需要使用动态PIVOT。

此外,您需要确保可以将tagIndex值组合在一行中。例如,不同的日期(在我的测试数据中),ID列在插入行时标记或其他内容(组ID列或日期添加列)。

答案 1 :(得分:1)

我认为可以使用这样的查询:

;with t as (
  select *
    , row_number() over (partition by [Date],[Tagindex] order by (select 0)) seq
  from tblTag
)
select [Date],
  max(case when [Tagindex] = 0 then [Value] end) '0',
  max(case when [Tagindex] = 1 then [Value] end) '1',
  max(case when [Tagindex] = 2 then [Value] end) '2'
from t
group by [Date], seq;

SQL Server Fiddle Demo
SQL Server Fiddle Demo - with pivot

注意:在上面的查询中,我使用row_number()函数为每个DateTagindex创建序列号,但诀窍是使用临时(select 0)按部分顺序使用的字段,不会信任返回插入行的任意顺序。因此,如果需要实现可信结果集;你需要有一个额外的字段,如datetime或自动增量字段。