代码之家  ›  专栏  ›  技术社区  ›  bjurstrs

SQL中的Transpose表

  •  0
  • bjurstrs  · 技术社区  · 8 年前

    我用以下方式设置了一张桌子。

    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 回复  |  直到 8 年前
        1
  •  4
  •   John Pasquet    8 年前

    如果您只是试图将旧数据转换为新数据,则基本上需要使用暴力:

     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
        )
    
        2
  •  1
  •   Philip Kelley    8 年前

    假设任何月份和任何年份都有专栏,那么这很快就会变得丑陋。如果列已设置并硬编码,请使用@John Pasquet的解(+1)。如果您需要处理MMMMDD_Type格式的任何列集,这里有一个提纲。

    第一遍:

    • 编写一个 SELECT... UNPIVOT... 查询以转换表
    • 将结果“label”列映射到Date数据类型和“Type”(订单、账单)

    然而,映射结果集 列名 “2015年7月15日”到“2015年6月1日”(或2015年7月月1日)即使不疯狂也很难。这将导致第二次传递:

    • 从sys构建列的“查找”列表。表和sys.colmns
    • 挑选出那些不受歧视的人
    • 找出每个日期和类型
    • 构建 选择…UNPIVOT。。。 在动态SQL中,将结果转储到临时表
    • 通过原始列名将此临时表连接到查找列表,该列名(通过连接)将获得准备好的日期和类型值

    说真的,这可能变得极其复杂。聪明的钱是重新构建带有日期和类型列的表。

        3
  •  1
  •   marc_s    8 年前

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

    在您知道old_col到new_col的列中,只需获取值并保存在一个变量中,对于其他列,您需要为每个月创建条件,如“contains june”,并保存在两个变量date和value中,之后每次您找到一个值为>的新月时,都需要创建条件;0对包含所有变量的新表执行插入操作。