【问题标题】:How to pivot across two columns using MS SQL如何使用 MS SQL 在两列之间进行透视
【发布时间】:2016-01-20 13:56:06
【问题描述】:

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

值表:

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

有没有更简洁的方法来归档所需的输出,比如跨两列旋转?

【问题讨论】:

  • 这似乎是自加入的场景。与枢轴无关。
  • 您希望每个 ID 有多少行?请说明您的 RDBMS(供应商和版本)
  • 如果您提供更多示例数据来实际演示您正在尝试做的事情,这可能会有所帮助。
  • 您好,如果我的回答帮助您解决了您的问题,您将非常感谢您投票和/或将其标记为已接受。如果没有,请发表评论您还需要什么...

标签: sql sql-server pivot-table


【解决方案1】:

在 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

【讨论】:

    猜你喜欢
    • 2020-05-26
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多