2013-02-26 16 views
6

Ho una tabella sql con valore corrente e valore precedente.SQL Server converte colonne in righe

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

Voglio confrontarli e visualizzarli nella seguente tabella se il valore è cambiato.

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

È possibile in SQL 2008 senza eseguire il ciclo di ogni colonna?

risposta

10

È possibile utilizzare un CROSS APPLY per UNPIVOT i dati:

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; 

Vedi SQL Fiddle with Demo.

Solo perché mi piace usare il perno funzione di , qui è una versione che utilizza sia il UNPIVOT e la perno funzioni per ottenere il risultato:

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 

Vedi SQL Fiddle with Demo

+0

+1 perché non sapevo che potevi usare CROSS APPLY in quel modo! –

+0

+1 per avere blu ... err intendo fornire un violino SQL. – Kermit

+0

grazie, è molto utile. – developer

6

Ecco un modo semplice:

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 me! – JNK

+0

grazie per la rapida risposta. – developer

0

Che ne dici di usare un sindacato:

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

Infine, e per completezza, c'è un comando UNPIVOT. Tuttavia, dal momento che hai due colonne da rimuovere, probabilmente sarebbe più semplice utilizzare una delle altre soluzioni.

Problemi correlati