sql >> Databáze >  >> RDS >> Oracle

Oracle SQL Transpose

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;

Viz SQL Fiddle s ukázkou




  1. Nastavte časovou část proměnné datetime

  2. Jak mohu získat návratovou hodnotu ze systémové zprávy SQL Server?

  3. Python MySQLdb iteruje tabulkou

  4. Postgres hierarchické (jsonb) CTE zbytečně pomalé