Oracle
 sql >> Database >  >> RDS >> Oracle

Istruzione SQL per unire e fornire risultati in più colonne

Non hai specificato l'RDBMS, ma questo è fondamentalmente un pivot se il tuo database ha accesso a quella funzione. In caso contrario, puoi replicare utilizzando un case e una funzione aggregata.

MySQL :

select name,
  sum(case when group_rn = 1 then amount else 0 end) Amount1,
  sum(case when group_rn = 2 then amount else 0 end) Amount2,
  sum(case when group_rn = 3 then amount else 0 end) Amount3
from
(
  select name,
    @num := if(@name = `name`, @num + 1, 1) as group_rn,
    @name := `name` as dummy,
    amount
  from
  (
    select p.name,
      d.amount,
      d.decl_id
    from person p
    inner join declaration d
      on p.person_id = d.person_id
  ) src
  order by name
) p
group by name

Vedi SQL Fiddle con demo

In SQL Server e Oracle il PIVOT la funzione esiste:

SQL Server :

select name,
  [1] as Amount1,
  [2] as Amount2,
  [3] as Amount3
from
(
  select p.name,
    d.amount,
    row_number() over(partition by p.name order by d.amount) rn
  from person p
  inner join declaration d
    on p.person_id = d.person_id
) src
pivot
(
  sum(amount)
  for rn in ([1], [2], [3])
) p

Vedi SQL Fiddle con demo

Puoi creare versioni dinamiche, nel caso tu abbia un numero imprecisato di importi che vuoi trasformare in colonne.

Modifica, hai dichiarato di utilizzare Oracle, quindi le risposte specifiche per Oracle sono di seguito:

Oracolo 11g ha il pivot funzione:

select name,
  Amount1,
  Amount2,
  Amount3
from
(
  select p.name,
    d.amount,
    row_number() over(partition by p.name order by d.amount) rn
  from person p
  inner join declaration d
    on p.person_id = d.person_id
) src
pivot
(
  sum(amount)
  for rn in ('1' as Amount1, '2' as Amount2, '3' as Amount3)
) p

Vedi SQL Fiddle con demo

Se non utilizzi Oracle 11g, dovrai utilizzare un CASE con funzione di aggregazione:

select name,
  sum(case when rn = 1 then amount else 0 end) Amount1,
  sum(case when rn = 2 then amount else 0 end) Amount2,
  sum(case when rn = 3 then amount else 0 end) Amount3
from
(
  select p.name,
    d.amount,
    row_number() over(partition by p.name order by d.amount) rn
  from person p
  inner join declaration d
    on p.person_id = d.person_id
) src
group by name

Vedi SQL Fiddle con demo