Suggerirei di applicare la funzione UNPIVOT prima a più colonne, quindi di utilizzare row_number()
per creare i tuoi nuovi nomi di colonna che verranno utilizzati nel PIVOT.
La sintassi di base per l'annullamento del pivot sarà
select field,
value,
'value'||
to_char(row_number() over(partition by field
order by value)) seq
from yourtable
unpivot
(
value
for field in (Name, Age, Sex, DOB, col1, col2, col3)
) u;
Vedi SQL Fiddle con demo
. Questo convertirà più colonne di dati in più righe. Ho usato row_number()
per creare un valore univoco per i nuovi nomi di colonna, i dati di questa query sono simili a:
| FIELD | VALUE | SEQ |
|-------|-------------------------|--------|
| AGE | 12 | value1 |
| AGE | 15 | value2 |
| COL1 | aa | value1 |
| COL1 | xx | value2 |
Quindi puoi applicare la funzione PIVOT a questo risultato:
select field, value1, value2
from
(
select field,
value,
'value'||
to_char(row_number() over(partition by field
order by value)) seq
from yourtable
unpivot
(
value
for field in (Name, Age, Sex, DOB, col1, col2, col3)
) u
) d
pivot
(
max(value)
for seq in ('value1' as value1, 'value2' as value2)
) piv
Vedi SQL Fiddle con demo . Questo dà un risultato finale:
| FIELD | VALUE1 | VALUE2 |
|-------|-------------------------|-------------------------|
| AGE | 12 | 15 |
| COL1 | aa | xx |
| COL2 | bb | yy |
| COL3 | cc | zz |
| DOB | 07-Aug-2001 12:00:00 AM | 26-Aug-2001 12:00:00 AM |
| NAME | A | B |
| SEX | F | M |
Nota, quando applichi la funzione unpivot, il tipo di dati di tutte le colonne deve essere lo stesso, quindi potresti dover convertire i tuoi dati in una sottoquery prima di poterli annullare.
La funzione UNPIVOT/PIVOT è stata introdotta in Oracle 11g, se stai utilizzando Oracle 10g, puoi modificare la query da utilizzare:
with cte as
(
select 'name' field, name value
from yourtable
union all
select 'Age' field, Age value
from yourtable
union all
select 'Sex' field, Sex value
from yourtable
union all
select 'DOB' field, DOB value
from yourtable
union all
select 'col1' field, col1 value
from yourtable
union all
select 'col2' field, col2 value
from yourtable
union all
select 'col3' field, col3 value
from yourtable
)
select
field,
max(case when seq = 'value1' then value end) value1,
max(case when seq = 'value2' then value end) value2
from
(
select field, value,
'value'||
to_char(row_number() over(partition by field
order by value)) seq
from cte
) d
group by field;
Vedi SQL Fiddle con demo