2013-02-26 24 views
6

Ich habe eine SQL-Tabelle mit dem aktuellen Wert und früheren Wert.SQL Server konvertieren Spalten in Zeilen

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

Ich möchte sie vergleichen und in einer der folgenden Tabelle angezeigt, wenn der Wert geändert hat.

Id Column Value Pvalue 
1 Value2 V  V1 
2 Value1 B  B1 
2 Value2 W  W1 
3 Value1 C  C1 

Ist es in SQL 2008 möglich, ohne jede Spalte zu durchlaufen? Hier

Antwort

10

Sie können eine CROSS APPLY verwenden, um die Daten zu UNPIVOT:

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; 

Siehe SQL Fiddle with Demo.

Nur weil ich liebe die Dreh Funktion, hier ist eine Version, die sowohl die Entpivotisierung verwendet und die Dreh Funktionen das Ergebnis zu erhalten:

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 

Siehe SQL Fiddle with Demo

+0

+1, weil ich nicht wusste, dass Sie CROSS APPLY auf diese Weise verwenden könnten! –

+0

+1 für blau zu haben ... err ich meine eine SQL-Geige zu bieten. – Kermit

+0

danke, es ist sehr nützlich. – developer

6

ist eine einfache Möglichkeit:

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

+1 - Beat mich dazu! – JNK

+0

danke für die schnelle antwort. – developer

0

Wie wäre es mit einer 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 
0

Schließlich, und der Vollständigkeit halber, gibt es einen UNPIVOT Befehl. Da Sie jedoch zwei Spalten haben, die Sie entfernen möchten, ist es wahrscheinlich einfacher, eine der anderen Lösungen zu verwenden.

Verwandte Themen