Oracle
 sql >> Base de données >  >> RDS >> Oracle

Instruction SQL pour joindre et donner un résultat dans plusieurs colonnes

Vous n'avez pas spécifié le SGBDR, mais il s'agit essentiellement d'un pivot si votre base de données a accès à cette fonction. Sinon, vous pouvez répliquer en utilisant un case et une fonction d'agrégation.

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

Voir SQL Fiddle avec démo

Dans SQL Server et Oracle, le PIVOT fonction existe :

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

Voir SQL Fiddle avec démo

Vous pouvez créer des versions dynamiques, dans le cas où vous avez un nombre inconnu de montants que vous souhaitez transformer en colonnes.

Edit, vous avez indiqué que vous utilisez Oracle, donc les réponses spécifiques à Oracle sont ci-dessous :

Oracle 11g a le pivot fonction :

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

Voir SQL Fiddle avec démo

Si vous n'êtes pas sur Oracle 11g, alors vous devrez utiliser un CASE avec fonction d'agrégat :

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

Voir SQL Fiddle avec démo