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

PIVOT basado en Oracle con grupo de columnas múltiples

Está girando sobre un valor fijo, el literal de cadena 'RM' , por lo que realmente no está haciendo nada útil en el pivote:el resultado es el mismo que obtendría al ejecutar la consulta 'pivot_data' por sí sola:

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

Quiere las workhrs agregadas por cada empleado, y un pivote de las habitaciones que vendieron. Si cambia esa consulta para obtener la suma analítica de workhrs y una clasificación de los valores de habitación/scr (y usando la sintaxis de unión moderna) obtienes:

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

Luego puede pivotar sobre ese rnk generado 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                                            

Debe saber el número máximo de habitaciones que puede tener cualquier empleado, es decir, el rnk más alto podría ser alguna vez - e incluir todos aquellos en el in cláusula. Lo que significa que es probable que termine con columnas vacías, como en este ejemplo donde no hay datos para 3_room o 3_scr . Sin embargo, no puede evitarlo, a menos que obtenga un resultado XML o genere la consulta dinámicamente.