Domanda

Abbiamo un tavolo che è della forma:

ID,Value1,Value2,Value3
1,2,3,4

Abbiamo bisogno di trasformare questo in.

ID,Name,Value
1,'Value1',2
1,'Value2',3
1,'Value3',4

C'è un modo intelligente di fare questo in un'istruzione SELECT (cioè senza UNION)? I nomi delle colonne valore1, valore2 e valore3 sono fissi e costanti.

Il database è Oracle 9i.

È stato utile?

Soluzione

Questo funziona su Oracle 10g:

select id, 'Value' || n as name,
       case n when 1 then value1 when 2 then value2 when 3 then value3 end as value
from (select rownum n
      from (select 1 from dual connect by level <= 3)) ofs, t

Credo che Oracle 9i aveva query ricorsive? Comunque, sono abbastanza sicuro che ha il supporto CASE, quindi, anche se non ha query ricorsive, si può solo fare "(selezionare 1 dalla doppia unione tutto selezionare 2 da dual union all select 3 dal doppio) OFS", invece. Abusando query ricorsive è un po 'più generale- per Oracle. (Utilizzando i sindacati per generare righe è portabile su altri DB, però)

Altri suggerimenti

Dare un union un colpo.

select ID, 'Value1' as Name, Value1 as Value from table_name union all
select ID, 'Value2', Value2 as Value from table_name union all
select ID, 'Value3', Value3 as Value from table_name

order by ID, Name

utilizzando union all significa che il server non eseguirà un distinct (che è implicito nelle operazioni union). Non dovrebbe fare alcuna differenza con i dati (dal momento che il proprio ID di spera, dovrebbe essere diverso), ma potrebbe accelerarlo un po '.

Si può fare in questo modo, ma non è abbastanza:

SELECT id,'Value 1' AS name,value1 AS value FROM mytable
UNION
SELECT id,'Value 2' AS name,value2 AS value FROM mytable
UNION
SELECT id,'Value 3' AS name,value3 AS value FROM mytable

Unioning tre select dovrebbe fare il trucco:

SELECT ID, 'Value1', Value1 AS Value
FROM TABLE
UNION
SELECT ID, 'Value2', Value2 AS Value
FROM TABLE
UNION
SELECT ID, 'Value3', Value3 AS Value
FROM TABLE

Se si utilizza SQL Server 2005 + quindi è possibile utilizzare UNPIVOT

CREATE TABLE #tmp ( ID int, Value1 int, Value2 int, Value3 int)

INSERT INTO #tmp (ID, Value1, Value2, Value3) VALUES (1, 2, 3, 4)

SELECT
    *
FROM
    #tmp

SELECT
    *
FROM
    #tmp
UNPIVOT
(
    [Value] FOR [Name] IN (Value1, Value2, Value3)
) uPIVOT

DROP TABLE #tmp

A UNION ALL, come altri hanno suggerito, è probabilmente la soluzione migliore in SQL. Si potrebbe anche prendere in considerazione la gestione di questo, alla fine, di fronte a seconda di cosa i vostri requisiti specifici.

sintassi CTE può essere diverso per Oracle (Mi sono imbattuto in Teradata), ma ho usato solo CTE per fornire dati di test, quelli 1 2 3 e 4. È possibile utilizzare tabella temporanea, invece. La dichiarazione reale è select SQL plain vanilla e sarà su qualsiasi database relazionale.

Per SQL Server, considerare UNPIVOT come alternativa a UNION:

SELECT id, value, colname
FROM #temp t
UNPIVOT (Value FOR ColName IN (value1,value2,value3)) as X

Ciò restituirà il nome della colonna pure. Non sono sicuro che cosa la X è usato per, ma non si può lasciare fuori.

Prova questo:

CTE crea una tabella temporanea con 4 valori. È possibile eseguire questo come in qualsiasi database.

with TEST_CTE (ID) as

(select * from (select '1' as a) as aa  union all
select * from (select '2' as b) as bb  union all
select * from (select '3' as c) as cc  union all
select * from (select '4' as d) as dd )

select a.ID, 'Value'|| a.ID, b.ID
from TEST_CTE a, TEST_CTE b
where b.ID = (select min(c.ID) from TEST_CTE c where c.ID > a.ID)

Ecco il set di risultati:

1   Value1  2

2   Value2  3

3   Value3  4

Enjoy!

Alcuni ripensamenti.

^^^ CTE sintassi può essere diverso in Oracle. Potrei eseguito solo in Teradata. È possibile sostituirlo con tabella temporanea o fissare la sintassi per renderlo compatibile con Oracle. L'istruzione SELECT è SQL plain vanilla che funziona su qualsiasi database.

^^^ Un'altra cosa da notare. Se il campo ID è numerico, potrebbe essere necessario lanciare in CHAR per concatenare con "Valore".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top