sql >> Base de Datos >  >> RDS >> Oracle

Declaración SQL para unir y dar resultado en múltiples columnas

No especificó el RDBMS, pero esto es básicamente un pivot si su base de datos tiene acceso a esa función. De lo contrario, puede replicar usando un case y una función agregada.

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

Consulte SQL Fiddle con demostración

En SQL Server y Oracle el PIVOT la función existe:

Servidor SQL :

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

Consulte SQL Fiddle con demostración

Puede crear versiones dinámicas, en caso de que tenga un número desconocido de cantidades que desee convertir en columnas.

Editar, dijo que está usando Oracle, por lo que las respuestas específicas de Oracle están a continuación:

Oráculo 11g tiene el pivot función:

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

Consulte SQL Fiddle con demostración

Si no está en Oracle 11g, deberá usar un CASE con función agregada:

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

Consulte SQL Fiddle con demostración