Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle-basiertes PIVOT mit mehreren Spaltengruppen

Sie drehen sich um einen festen Wert, das String-Literal 'RM' , also machen Sie im Pivot wirklich nichts Nützliches - die Ausgabe ist die gleiche, die Sie erhalten würden, wenn Sie die Abfrage "pivot_data" alleine ausführen würden:

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

Sie möchten die aggregierten workhrs für jeden Mitarbeiter und ein Pivot der von ihnen verkauften Zimmer. Wenn Sie diese Abfrage ändern, um die analytische Summe von workhrs zu erhalten und eine Rangfolge der room/scr-Werte (und mit moderner Join-Syntax) erhalten Sie:

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

Sie können dann auf diesen generierten rnk umschwenken Zahl:

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                                            

Sie müssen wissen, wie viele Zimmer ein Mitarbeiter maximal haben darf – also die höchste rnk jemals sein könnte - und fügen Sie all diese in den in ein Klausel. Das bedeutet, dass Sie am Ende wahrscheinlich leere Spalten haben werden, wie in diesem Beispiel, wo es keine Daten für 3_room gibt oder 3_scr . Das können Sie jedoch nicht vermeiden, es sei denn, Sie erhalten ein XML-Ergebnis oder generieren die Abfrage dynamisch.