sql >> Database >  >> RDS >> Oracle

SQL-instructie om mee te doen en resultaat in meerdere kolommen te geven

Je hebt het RDBMS niet gespecificeerd, maar dit is in feite een pivot als uw database toegang heeft tot die functie. Zo niet, dan kunt u repliceren met een case en een aggregatiefunctie.

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

Zie SQL Fiddle met demo

In SQL Server en Oracle de PIVOT functie bestaat:

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

Zie SQL Fiddle met demo

U kunt dynamische versies maken, voor het geval u een onbekend aantal bedragen heeft dat u in kolommen wilt omzetten.

Bewerken, je hebt aangegeven dat je Oracle gebruikt, dus Oracle-specifieke antwoorden staan ​​hieronder:

Oracle 11g heeft de pivot functie:

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

Zie SQL Fiddle met demo

Als u Oracle 11g niet gebruikt, moet u een CASE . gebruiken met aggregatiefunctie:

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

Zie SQL Fiddle met demo



  1. Is het mogelijk om een ​​variabele door te geven aan een opgeslagen procedure-aanroep in mysql?

  2. Achterwaartse scan van SQL Server-index:begrijpen, afstemmen

  3. Fout in tabelsyntaxis maken

  4. Hoe een bestaande Postgres-tabel zo transparant mogelijk naar een gepartitioneerde tabel migreren?