【问题标题】:How to Convert Columns to Rows and Replace Column Names如何将列转换为行并替换列名
【发布时间】:2018-05-13 08:19:49
【问题描述】:

我有一个表格,可以连续返回月份的产品数量,例如:

[M02] | [M03] | [M04] | [M05] | [M06] | [M07] | [M08] | [M09] |[M10] | [M11] | [M12]
------------------------------------------------------------------------------------
120   | 65    | 75    | 587   | [78   | 5656  | 651   | 65    | 8949 | 89   | 596

现在我需要结果,因为 [这里我想将列替换为行并将它们的名称更改为我选择的别名] 例如从列到行的 M01 到一月

  [Month]  | [Count] |
----------------------
  January  |     120 |
  February |     65  |

我知道我可以使用 UnPivot 运算符实现这一点,但我无法将月份名称设为一月,因为我无法在 unpivot 中设置别名

我写了这个查询

SELECT [Months],[Count]
  FROM [TableName]
  UnPivot(
  [Count] for Months in ([M01]
      ,[M02]
      ,[M03]
      ,[M04]
      ,[M05]
      ,[M06]
      ,[M07]
      ,[M08]
      ,[M09]
      ,[M10]
      ,[M11]
      ,[M12])
  ) as unpiv

这给了我数据:

      [Month]  | [Count] |
    ----------------------
      M01      |     120 |
      M02      |     65  |

这里 M01、M02 等分别是月份,但我不能更改它们的名称。我怎样才能做到这一点?

【问题讨论】:

    标签: sql sql-server database sql-server-2008 sql-server-2012


    【解决方案1】:

    方法一:使用CASE WHEN

    您可以像下面这样使用CASE WHEN 来获得所需的输出。

    SELECT    
        (CASE 
        WHEN [Months]= 'M01' then 'January'
        WHEN [Months]= 'M02' then 'February'
            --PUT Remaning conditions
        END) [Months],
        [Count]
    
    FROM
    (
    SELECT [Months],[Count]
        FROM [TableName]
        UnPivot(
        [Count] for Months in ([M01]
            ,[M02]
            ,[M03]
            ,[M04]
            ,[M05]
            ,[M06]
            ,[M07]
            ,[M08]
            ,[M09]
            ,[M10]
            ,[M11]
            ,[M12])
        ) as unpiv
    )T
    

    方法2:INNER JOIN映射表

    您可以有一个映射表,在其中将您的代码与月份进行映射,并放置一个INNER JOIN 之类的

    SELECT 
    MP.MonthName,
    T.[Count]
    FROM
    (
    SELECT [Months],[Count]
      FROM [TableName]
      UnPivot(
      [Count] for Months in ([M01]
          ,[M02]
          ,[M03]
          ,[M04]
          ,[M05]
          ,[M06]
          ,[M07]
          ,[M08]
          ,[M09]
          ,[M10]
          ,[M11]
          ,[M12])
      ) as unpiv
    )t
    INNER JOIN [YourMappingTable] MP ON MP.Code=T.Months
    

    方法 3:字符串函数。

    另一种方法是使用RIGHTPATINDEX 来获取数字,最后将数字转换为月份名称。

    SELECT 
    DateName( month , DateAdd( month ,  CAST(RIGHT(T.[Months],PATINDEX('%[0-9]%',T.[Months])) AS INT) , 0 ) - 1 ) as Months,
    [Count]
    FROM
    (
    SELECT [Months],[Count]
      FROM [TableName]
      UnPivot(
      [Count] for Months in ([M01]
          ,[M02]
          ,[M03]
          ,[M04]
          ,[M05]
          ,[M06]
          ,[M07]
          ,[M08]
          ,[M09]
          ,[M10]
          ,[M11]
          ,[M12])
      ) as unpiv
    )t
    

    注意:如果格式是固定的,也可以不使用PATINDEX,如下尝试

    DateName( month , DateAdd( month ,  CAST(RIGHT(T.[Months],2) AS INT) , 0 ) - 1 ) as Months,
    

    【讨论】:

    • 感谢您非常详细的解释。感谢您的帮助
    【解决方案2】:

    您不能在 UNPIVOT 函数内分配别名,因此您必须使用 CASE 表达式。

    【讨论】:

      猜你喜欢
      • 2023-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 2021-07-17
      • 1970-01-01
      相关资源
      最近更新 更多