【问题标题】:How to unpivot this table如何取消透视此表
【发布时间】:2014-08-20 09:42:39
【问题描述】:

我创建了一个临时表,我想将其取消透视,但我不断收到如下错误消息: 消息 156,第 15 级,状态 1,第 196 行 关键字“for”附近的语法不正确。

我的临时表如下:

档案订单号 T_Code Routine_Labour Variable_Labour

我想将其还原到下面:

我使用了下面的脚本:

Select 
Dossier,
Order_Number,
T_Code,
Labour_Type,
Amount

from 
#LabourSplit

Unpivot 
(
 Amount for Labour_Type in (Routine_Labour, Variable_Labour)
 ) as LabourSplit_U

我一运行这个脚本,就会弹出错误消息。即使我注释掉了临时表和脚本中的两列,错误消息仍然存在。

Select 
Dossier,
--Order_Number,
--T_Code,
Labour_Type,
Amount

from 
#LabourSplit

Unpivot 
(
 Amount for Labour_Type in (Routine_Labour, Variable_Labour)
 ) as LabourSplit_U

【问题讨论】:

  • 你能复制粘贴这些行而不是把它们作为图像吗?
  • 您使用的是什么版本的 SQL Server?您要连接的数据库的兼容级别是多少?
  • @MartinSmith 那是 SQL Server 2012。不确定数据库的兼容性级别。我认为这可能与版本有关。因为即使我运行在线示例也会出现相同的错误。 ingenioussql.com/2013/05/09/standard-t-sql-unpivot

标签: sql sql-server sql-server-2012 temp-tables unpivot


【解决方案1】:

试试这个:

Select 
Dossier,
Order_Number,
T_Code,
Labour_Type,
Amount
FROM
(
  Select 
  Dossier,
  Order_Number,
  T_Code,
  Routine_Labour, 
  Variable_Labour
  from #LabourSplit
) a
Unpivot 
(
  Amount for Labour_Type in (Routine_Labour, Variable_Labour)
) as LabourSplit_U

SQL Fiddle

结果:

| DOSSIER | ORDER_NUMBER | T_CODE |     LABOUR_TYPE | AMOUNT |
|---------|--------------|--------|-----------------|--------|
|    1234 |         5678 |      1 |  Routine_Labour |     10 |
|    1234 |         5678 |      1 | Variable_Labour |     20 |
|    1234 |         3434 |      1 |  Routine_Labour |     20 |
|    1234 |         3434 |      1 | Variable_Labour |     70 |
|    1234 |         5671 |      1 |  Routine_Labour |     30 |
|    1234 |         5671 |      1 | Variable_Labour |     10 |
|    1234 |         3422 |      1 |  Routine_Labour |     40 |
|    1234 |         3422 |      1 | Variable_Labour |     40 |
|    1234 |         1122 |      1 |  Routine_Labour |     11 |
|    1234 |         1122 |      1 | Variable_Labour |     30 |

但是,据我所知,完整版本的 SQL Server 支持 UNPIVOT。如果您有精简版或其他免费版本,您需要使用UNION ALL

Select 
Dossier,
Order_Number,
T_Code,
'Routine_Labour' AS Labour_Type,
Routine_Labour AS Amount
FROM LabourSplit
UNION ALL 
Select 
Dossier,
Order_Number,
T_Code,
'Variable_Labour' AS Labour_Type,
Variable_Labour AS Amount
FROM LabourSplit
ORDER BY 1,2,3

检查这个SQL Fiddle

结果:

| DOSSIER | ORDER_NUMBER | T_CODE |     LABOUR_TYPE | AMOUNT |
|---------|--------------|--------|-----------------|--------|
|    1234 |         1122 |      1 |  Routine_Labour |     11 |
|    1234 |         1122 |      1 | Variable_Labour |     30 |
|    1234 |         3422 |      1 | Variable_Labour |     40 |
|    1234 |         3422 |      1 |  Routine_Labour |     40 |
|    1234 |         3434 |      1 |  Routine_Labour |     20 |
|    1234 |         3434 |      1 | Variable_Labour |     70 |
|    1234 |         5671 |      1 | Variable_Labour |     10 |
|    1234 |         5671 |      1 |  Routine_Labour |     30 |
|    1234 |         5678 |      1 |  Routine_Labour |     10 |
|    1234 |         5678 |      1 | Variable_Labour |     20 |

【讨论】:

  • 不是 SQL Server 2008,或者您的 Routine_Labour 和 Variable_Labour 的数据类型不同。检查小提琴:sqlfiddle.com/#!3/294e4/1
  • 非常感谢。我的是 SQL Server 2012。那么我可以用 2012 版本做什么?
  • 这是 SQL Server 2012 的小提琴。在那里也可以工作。 sqlfiddle.com/#!6/294e4/1
  • 除非您的 SQL Server 是“精简版”,或者是完整版的其他部分内容
  • 留在我身边,我会给你另一种可行的解决方案
【解决方案2】:

我认为 CROSS APPLY VALUES 比 UNPIVOT 更易于使用和理解

SELECT Dossier
      ,Order_Number
      ,T_Code
      ,Labour_Type
      ,Amount
FROM #LabourSplit
     CROSS APLLY (
         VALUES (Routine_Labour, 'Routine_Labour')
               ,(Variable_Labour, 'Variable_Labour')
     ) AS CA1(Amount, Labour_Type)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-26
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多