Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle SQL-Transponierung

Ich würde vorschlagen, die UNPIVOT-Funktion zuerst auf Ihre mehreren Spalten anzuwenden und dann row_number() zu verwenden um Ihre neuen Spaltennamen zu erstellen, die im PIVOT verwendet werden.

Die grundlegende Syntax für das Unpivot lautet

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;

Siehe SQL-Fiddle mit Demo . Dadurch werden Ihre mehreren Datenspalten in mehrere Zeilen konvertiert. Ich habe row_number() verwendet Um einen eindeutigen Wert für Ihre neuen Spaltennamen zu erstellen, sehen die Daten aus dieser Abfrage wie folgt aus:

| FIELD |                   VALUE |    SEQ |
|-------|-------------------------|--------|
|   AGE |                      12 | value1 |
|   AGE |                      15 | value2 |
|  COL1 |                      aa | value1 |
|  COL1 |                      xx | value2 |

Dann können Sie die PIVOT-Funktion auf dieses Ergebnis anwenden:

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

Siehe SQL Fiddle mit Demo . Dies ergibt ein Endergebnis:

| 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 |

Beachten Sie, dass beim Anwenden der Unpivot-Funktion der Datentyp aller Spalten derselbe sein muss, sodass Sie Ihre Daten möglicherweise in einer Unterabfrage konvertieren müssen, bevor Sie sie entpivozieren können.

Die UNPIVOT/PIVOT-Funktion wurde in Oracle 11g eingeführt. Wenn Sie Oracle 10g verwenden, können Sie die zu verwendende Abfrage bearbeiten:

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;

Siehe SQL Fiddle mit Demo