Doporučuji nejprve použít funkci UNPIVOT na více sloupců a poté použít row_number()
k vytvoření nových názvů sloupců, které budou použity v PIVOTu.
Základní syntaxe pro unpivot bude
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;
Viz SQL Fiddle s ukázkou
. Tím převedete více sloupců dat na více řádků. Použil jsem row_number()
Chcete-li vytvořit jedinečnou hodnotu pro vaše nové názvy sloupců, data z tohoto dotazu vypadají takto:
| FIELD | VALUE | SEQ |
|-------|-------------------------|--------|
| AGE | 12 | value1 |
| AGE | 15 | value2 |
| COL1 | aa | value1 |
| COL1 | xx | value2 |
Poté můžete na tento výsledek použít funkci PIVOT:
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
Viz SQL Fiddle s ukázkou . To dává konečný výsledek:
| 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 |
Všimněte si, že když používáte funkci unpivot, datový typ všech sloupců musí být stejný, takže možná budete muset převést data v poddotazu, než je budete moci zrušit.
Funkce UNPIVOT/PIVOT byla zavedena v Oracle 11g, pokud používáte Oracle 10g, můžete upravit dotaz a použít:
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;