Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

PIVOT baseado em Oracle com grupo de várias colunas


Você está girando em um valor fixo, a string literal 'RM' , então você realmente não está fazendo nada útil no pivô - a saída é a mesma que você obteria executando a consulta 'pivot_data' por conta própria:
SELECT eNAME,workhrs,room, SCR from PRODUCTIVITY p,PRODUCTIVITYd d, emp e, ROOMS R
where p.PRODUCTIVITYID=d.PRODUCTIVITYID and e.empno=p.employeeid
AND R.ID=P.ROOMID;

ENAME    WORKHRS       ROOM        SCR
----- ---------- ---------- ----------
JONES        3.6        101         53
ALLEN       1.32        101         43
ALLEN          6        102         22

Você quer o agregado workhrs para cada funcionário e um pivô dos quartos que vendiam. Se você alterar essa consulta para obter a soma analítica de workhrs e uma classificação dos valores room/scr (e usando a sintaxe de junção moderna) você obtém:
select e.ename, r.room, p.scr,
  sum(d.workhrs) over (partition by e.ename) as wrkhrs,
  rank() over (partition by e.ename order by r.room, p.scr) as rnk
from productivity p
join productivityd d on d.productivityid = p.productivityid
join emp e on e.empno=p.employeeid
join rooms r on r.id = p.roomid;

ENAME       ROOM        SCR     WRKHRS        RNK
----- ---------- ---------- ---------- ----------
ALLEN        101         43       7.32          1
ALLEN        102         22       7.32          2
JONES        101         53        3.6          1

Você pode então dinamizar nesse rnk gerado número:
with pivot_data as (
  select e.ename, r.room, p.scr,
    sum(d.workhrs) over (partition by e.ename) as wrkhrs,
    rank() over (partition by e.ename order by r.room, p.scr) as rnk
  from productivity p
  join productivityd d on d.productivityid = p.productivityid
  join emp e on e.empno=p.employeeid
  join rooms r on r.id = p.roomid
)
select *
from   pivot_data
pivot (
  min(room) as room, min(scr) as scr  --<-- pivot_clause
  for rnk                             --<-- pivot_for_clause        
  in  (1, 2, 3)                       --<-- pivot_in_clause         
);

ENAME     WRKHRS     1_ROOM      1_SCR     2_ROOM      2_SCR     3_ROOM      3_SCR
----- ---------- ---------- ---------- ---------- ---------- ---------- ----------
ALLEN       7.32        101         43        102         22                      
JONES        3.6        101         53                                            

Você precisa saber o número máximo de quartos que qualquer funcionário pode ter - ou seja, o maior rnk poderia ser - e inclua todos aqueles no in cláusula. O que significa que é provável que você acabe com colunas vazias, como neste exemplo, onde não há dados para 3_room ou 3_scr . Você não pode evitar isso, a menos que obtenha um resultado XML ou gere a consulta dinamicamente.