如何使用MS SQL在两列之间进行数据透视

时间:2016-01-20 13:56:07

标签: sql sql-server pivot-table

我有一个内容值表和内容类型表需要动态组合到一个聚合视图中。这里有一些伪数据来演示他们的架构和关系:

价值表:

ID      TYPEID      TEXT      MARKUP
1.           1.      "Some text"    "Some markup"
....

类型表:

ID       TYPENAME
1.       "Some type"
...

期望的输出:

ValueID          Sometype           SometypeMarkup        AnotherType        AnotherTypeMarkup   ...
1.                   "sometype text"           "sometype markup"      "anothertype text"       "anothertype markup"
2.          ....
...

目前我正在使用一个过程,使用如下两个数据透视表动态选择类型名称及其值:

Select p.valueid , @colunns from valuetable (pivot max(text) from (typenames in (@typecolums)) p) pt join (select * from valuetable pivot max(markup) from (typenames in (@typecolumns) pp) pm on pt.valueid = pm.valueid group by pt.valueid

是否有更整洁的方式来存档所需的输出,例如在两列之间进行旋转?

1 个答案:

答案 0 :(得分:0)

在SQL Server中,您可以使用PIVOT,但不能使用多个列

有一个技巧:连接数据并让它看起来像XML。这个复合数据是可转换的 - 因为它是XML - 你可以轻松地将它分类为类型安全:

DECLARE @tblType TABLE(ID INT,Caption VARCHAR(100));
INSERT INTO @tblType VALUES
 (1,'Type1')
,(2,'Type2')
,(3,'Type3');

DECLARE @tbl TABLE(ID INT,TYPEID INT,[TEXT] VARCHAR(100),MARKUP VARCHAR(100));
INSERT INTO @tbl VALUES
 (1,1,'type 11','markup 11')
,(1,2,'type 21','markup 21')
,(1,3,'type 31','markup 31')
,(2,2,'type 22','markup 22')
,(2,3,'type 32','markup 32')
,(3,1,'type 13','markup 13')
,(3,3,'type 33','markup 33');

SELECT p.ID
      ,Casted.Type1Xml.value('/x[1]','varchar(max)') AS Type1_Text 
      ,Casted.Type1Xml.value('/x[2]','varchar(max)') AS Type1_Markup 
      ,Casted.Type2Xml.value('/x[1]','varchar(max)') AS Type2_Text 
      ,Casted.Type2Xml.value('/x[2]','varchar(max)') AS Type2_Markup 
      ,Casted.Type3Xml.value('/x[1]','varchar(max)') AS Type3_Text 
      ,Casted.Type3Xml.value('/x[2]','varchar(max)') AS Type3_Markup 
FROM(
    SELECT tbl.ID 
          ,tp.Caption
          ,'<x>' + tbl.[TEXT] + '</x><x>' + tbl.MARKUP + '</x>' AS ConcatenatedData
    FROM @tbl AS tbl
    INNER JOIN @tblType AS tp ON tbl.TYPEID=tp.ID
) AS x
PIVOT
(
    MIN(ConcatenatedData) FOR Caption IN(Type1,Type2,Type3)
) AS p
CROSS APPLY
(
    SELECT CAST(p.Type1 AS XML) AS Type1Xml
          ,CAST(p.Type2 AS XML) AS Type2Xml 
          ,CAST(p.Type3 AS XML) AS Type3Xml 
) AS Casted

结果

1   type 11 markup 11   type 21 markup 21   type 31 markup 31
2   NULL    NULL        type 22 markup 22   type 32 markup 32
3   type 13 markup 13   NULL    NULL        type 33 markup 33