Je suggérerais d'appliquer d'abord la fonction UNPIVOT à vos multiples colonnes, puis d'utiliser row_number()
pour créer vos nouveaux noms de colonne qui seront utilisés dans le PIVOT.
La syntaxe de base pour l'unpivot sera
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;
Voir SQL Fiddle avec démo
. Cela va convertir vos multiples colonnes de données en plusieurs lignes. J'ai utilisé row_number()
pour créer une valeur unique pour vos nouveaux noms de colonne, les données de cette requête ressemblent à :
| FIELD | VALUE | SEQ |
|-------|-------------------------|--------|
| AGE | 12 | value1 |
| AGE | 15 | value2 |
| COL1 | aa | value1 |
| COL1 | xx | value2 |
Ensuite, vous pouvez appliquer la fonction PIVOT à ce résultat :
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
Voir SQL Fiddle avec démo . Cela donne un résultat final :
| 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 |
Notez que lorsque vous appliquez la fonction d'unpivot, le type de données de toutes les colonnes doit être le même, vous devrez donc peut-être convertir vos données dans une sous-requête avant de pouvoir l'unpivot.
La fonction UNPIVOT/PIVOT a été introduite dans Oracle 11g, si vous utilisez Oracle 10g, vous pouvez modifier la requête à utiliser :
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;
Voir SQL Fiddle avec démo