SQL Server将列转换为行

6

我有一张 SQL 表格,其中包括当前值和先前的值。

Id  Value1  PValue1 Value2  PValue2
1   A       A       V       V1
2   B       B1      W       W1
3   C       C1      X       X

如果数值发生变化,我想要将它们进行比较并显示在以下表格中。
Id  Column  Value   Pvalue
1   Value2  V       V1
2   Value1  B       B1
2   Value2  W       W1
3   Value1  C       C1

在SQL 2008中,是否有不需要逐列循环的方法呢?

4个回答

10
您可以使用 CROSS APPLY 来对数据进行旋转:
SELECT t.id,
  x.Col,
  x.Value,
  x.PValue
FROM YourTable t
CROSS APPLY 
(
    VALUES
        ('Value1', t.Value1, t.PValue1),
        ('Value2', t.Value2, t.PValue2)
) x (Col, Value, PValue)
where x.Value <> x.PValue;

请查看 SQL Fiddle with Demo

因为我喜欢使用 pivot 函数,所以这里提供了一个版本,它同时使用了 unpivotpivot 函数来获取结果:

select id, 
  colname,
  value,
  pvalue
from
(
  select id, 
    replace(col, 'P', '') colName,
    substring(col, 1, PatIndex('%[0-9]%', col) -1) new_col,  
    val
  from yourtable
  unpivot
  (
    val
    for col in (Value1, PValue1, Value2, PValue2)
  ) unpiv
) src
pivot
(
  max(val)
  for new_col in (Value, PValue)
) piv
where value <> pvalue
order by id

带演示的SQL Fiddle


+1 因为我不知道你可以以那种方式使用 CROSS APPLY! - Ann L.

6
这里有一个简单的方法:
SELECT  Id, 
        'Value1' [Column],
        Value1 Value,
        PValue1 PValue
FROM YourTable
WHERE ISNULL(Value1,'') != ISNULL(PValue1,'')
UNION ALL
SELECT  Id, 
        'Value2' [Column],
        Value2 Value,
        PValue2 PValue
FROM YourTable
WHERE ISNULL(Value2,'') != ISNULL(PValue2,'')

0
最后,为了完整起见,有一个UNPIVOT命令。然而,由于您想要解开两列,使用其他解决方案可能会更简单。

0
如何使用 union:
SELECT * FROM
    (SELECT Id, 'Value1' [Column], Value1 [Value], PValue1 [PValue]
    FROM table_name
    UNION ALL
    SELECT Id, 'Value2' [Column], Value2 [Value], PValue2 [PValue]
    FROM table_name)tmp
WHERE Value != PValue
ORDER BY Id

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接