在SQL中转置表

时间:2016-06-15 19:01:35

标签: sql tsql sql-server-2014 transpose

我按以下方式设置了表格。

CustomerNumber June15_Order June15_Billing July15_Order July15_Billing August15_Order August15_Billing
    12345           5               55         3              45
    5431            6               66         5              67

我希望它是:

CustomerNumber    Date       Order    Billing
    12345       01/06/2015     5         55
    12345       01/07/2015     3         45
    5431        01/06/2015     6         66
    5431        01/07/2015     5         67

有关如何准确转置此表的任何想法吗?

3 个答案:

答案 0 :(得分:4)

如果您只是想将旧数据添加到新数据中,您基本上需要使用暴力:

 INSERT INTO NewTable
     (CustomerNumber, [Date], [Order], Billing)
     ( 
        SELECT CustomerNumber, '06/15/2015', June15_Order, June15_Billing
        FROM OldTable

        UNION

        SELECT CustomerNumber, '07/15/2015', July15_Order, July15_Billing
        FROM OldTable

        UNION

        SELECT CustomerNumber, '08/15/2015', August15_Order, August15_Billing
        FROM OldTable
    )

答案 1 :(得分:1)

首先创建一个具有所需结构的新表,之后您将需要为该任务创建一个存储过程,该过程将遍历所有行。

在你知道old_col到new_col的列上,只需获取值并保存在变量中,对于其他人,您需要为每个月创建条件,例如"包含june"并保存两个变量date和value,之后每次找到一个值为>的新月份0使用所有变量对新表执行插入。

答案 2 :(得分:1)

假设任何月份和任何年份都有列,这会很快变得难看。如果列已设置并进行硬编码,请使用@John Pasquet的解决方案(+1)。如果您需要能够使用MMMMDD_Type形式的任何一组列,这里是一个大纲。

第一遍:

  • 编写SELECT... UNPIVOT...查询以转换表格
  • 将生成的“label”列映射到Date数据类型和“Type”(订单,结算)

然而,将“July15”的结果集列名映射到“2015年7月1日”(或2015年7月1日)很难,如果不是很难。这导致了第二次传递:

  • 从sys.tables和sys.colmns
  • 构建列的“查找”列表
  • 挑选那些不透露的内容
  • 找出每个日期和类型
  • 在动态SQL中构建SELECT... UNPIVOT...,将结果转储到临时表
  • 按原始列名称将此临时表连接到查找列表,该列名称(通过连接)为您提供准备日期和类型值

说真的,这可能会变得非常复杂。聪明的钱是用日期和类型的列重建表格。