在 SQL 中转置 table

Transpose table in SQL

我按以下方式设置了 table。

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

关于如何准确转置这个 table 有什么想法吗?

如果您只是想将旧数据转化为新数据,您基本上需要使用暴力破解:

 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
    )

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

在您知道的 old_col 到 new_col 的列上,只需取值并保存在变量中,对于其他列,您需要为每个月创建条件,例如 "contains june"并保存在两个变量日期和值中,之后每次找到值 > 0 的新月份时,对所有变量的新 table 执行插入。

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

第一关:

  • 编写一个 SELECT... UNPIVOT... 查询来转换 table
  • 将生成的 "label" 列映射到日期数据类型和 "Type"(订单、计费)

但是,将 "July15" 的结果集 列名称 映射到 "Jul 1, 2015"(或 01/07/2015)很难,甚至很难。这导致第二遍:

  • 从 sys.tables 和 sys.colmns
  • 构建一个 "lookup" 列列表
  • 挑出那些要逆透视的
  • 找出每个日期和类型
  • 在动态 SQL 中构建 SELECT... UNPIVOT...,将结果转储到临时 table
  • 按原始列名将此临时 table 加入查找列表,这(通过连接)为您提供准备好的日期和类型值

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