sql >> Database >  >> RDS >> Oracle

Oracle SQL-transponering

Ik zou willen voorstellen om eerst de UNPIVOT-functie toe te passen op uw meerdere kolommen en vervolgens row_number() te gebruiken om uw nieuwe kolomnamen te maken die in de PIVOT zullen worden gebruikt.

De basissyntaxis voor het ongedaan maken van het draaien is

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;

Zie SQL Fiddle met demo . Dit gaat uw meerdere kolommen met gegevens converteren naar meerdere rijen. Ik gebruikte row_number() om een ​​unieke waarde voor uw nieuwe kolomnamen te creëren, zien de gegevens van deze zoekopdracht er als volgt uit:

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

Vervolgens kunt u de PIVOT-functie op dit resultaat toepassen:

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

Zie SQL Fiddle met demo . Dit geeft een eindresultaat:

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

Let op:wanneer u de functie voor het ongedaan maken van draaien toepast, moet het gegevenstype van alle kolommen hetzelfde zijn, dus het kan zijn dat u uw gegevens in een subquery moet converteren voordat u deze kunt ongedaan maken.

De functie UNPIVOT/PIVOT is geïntroduceerd in Oracle 11g, als u Oracle 10g gebruikt, kunt u de query bewerken om te gebruiken:

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;

Zie SQL Fiddle met demo




  1. Hoe een databasetabel te beperken, zodat slechts één rij een bepaalde waarde in een kolom kan hebben?

  2. Rails converteert de tijdzone niet (PostgreSQL)

  3. SQL CASE en lokale variabelen

  4. De INSERT-instructie was in strijd met de FOREIGN KEY-beperking