Jag skulle föreslå att du tillämpar UNPIVOT-funktionen först på dina flera kolumner och sedan använder row_number()
för att skapa dina nya kolumnnamn som kommer att användas i PIVOT.
Grundsyntaxen för unpivoten kommer att vara
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;
Se SQL-fiol med demo
. Detta kommer att konvertera dina flera kolumner med data till flera rader. Jag använde row_number()
för att skapa ett unikt värde för dina nya kolumnnamn ser data från denna fråga ut så här:
| FIELD | VALUE | SEQ |
|-------|-------------------------|--------|
| AGE | 12 | value1 |
| AGE | 15 | value2 |
| COL1 | aa | value1 |
| COL1 | xx | value2 |
Sedan kan du använda PIVOT-funktionen på detta resultat:
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
Se SQL-fiol med demo . Detta ger ett slutresultat:
| 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 |
Observera att när du använder unpivot-funktionen måste datatypen för alla kolumner vara densamma så du kanske måste konvertera dina data i en underfråga innan du kan unpivot den.
UNPIVOT/PIVOT-funktionen introducerades i Oracle 11g, om du använder Oracle 10g kan du redigera frågan för att använda:
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;