基于Oracle的PIVOT多列组(Oracle based PIVOT with multiple

2019-11-04 04:22发布

使用下面的表格,

生产率:

PRODUCTIVITYID  PDATE   EMPLOYEEID  ROOMID  ROOMS_SOLD  SCR
81            03/26/2016    7499     21         56      43
82            03/26/2016    7566     42     -            -
102           03/26/2016    7499     22        434      22
101           03/26/2016    7566     21         43      53

ProductivityD:

PRODUCTIVITYID  WORKHRS MEALPANELTY DESCRIPTION
2                 50    4   -
21               6.4    1   -
102                6    -   -
81              1.32    -   -
101              3.6    -   - 

客房:

  ID    ROOM    PROPERTCODE
  22    102  6325
  41    103  6325
  42    104  6325
  43    105  6325

EMP:

EMPNO   ENAME   JOB     MGR     HIREDATE    SAL   COMM  DEPTNO
7566    JONES   MANAGER 7839    04/02/1981  2975    -   20
7788    SCOTT   ANALYST 7566    12/09/1982  3000    -   20
7902    FORD    ANALYST 7566    12/03/1981  3000    -   20
7369    SMITH   CLERK   7902    12/17/1980  800 -   20
7499    ALLEN   SALESMAN 7698   02/20/1981  1600    300 30

下面的查询产生以下输出,但我需要组employees和总和workhrs然后枢转RM_ROOMRM_SCR

WITH pivot_data AS (
SELECT eNAME,workhrs,room, 'RM' as RM,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
            )
    SELECT *
    FROM   pivot_data
    PIVOT (
          MIN(room) as room,min(scr) as SCR      --<-- pivot_clause
          FOR RM--<-- pivot_for_clause        
         IN  ('RM')    --<-- pivot_in_clause         
)

电流输出:

ENAME   WORKHRS 'RM'_ROOM 'RM'_SCR
JONES   3.6       101        53
ALLEN   6         102        22
ALLEN   1.32      101        43

所需的输出:

    ENAME   WORKHRS 'RM'_ROOM 'RM'_SCR 'RM'_ROOM 'RM'_SCR
    JONES   3.6          101     53      -         -
   ALLEN    7.32         101     43     102       22

Answer 1:

您正在旋转的固定值,字符串文字'RM' ,所以你真的没有做任何事情在枢轴有用-输出是一样的,你想运行在自己的“pivot_data”查询得到:

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

你想要的总workhrs为每一位员工,和他们卖了房枢轴。 如果更改查询得到的分析和workhrs和房间/ SCR值的排名(并利用现代联接语法),您可以:

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

然后,您可以在该支点产生rnk数:

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                                            

你需要知道房间的最大数量的任何雇员可能有-即最高rnk可能永远不会-而且包括所有那些在的in条款。 这意味着你很可能与空列到最后,因为在这个例子中,其中不存在用于数据3_room3_scr 。 你无法避免,虽然,除非你得到一个XML结果或动态生成的查询。



Answer 2:

你所说的是没有意义的。 你所说的“支点RM_ROOM”是什么意思? 所以我要猜。 我猜你想集团的员工和总和workhrs,然后转动的结果。 “输出”你看似乎是输出pivot_data,你的子查询。

你的回答将只有易名,并为他们每个人,小时计数工作。 所以,你不需要在pivot_data子查询选择房间号码。 你只需要为ename和workhrs。 然后,它是使用PIVOT语法的一个简单的问题:

WITH pivot_data AS (
    SELECT eNAME, workhrs FROM PRODUCTIVITY p,PRODUCTIVITYd d, emp e, ROOMS R
    where p.PRODUCTIVITYID=d.PRODUCTIVITYID and e.empno=p.employeeid
    AND R.ID=P.ROOMID
            )
SELECT *
FROM   pivot_data
PIVOT (
        SUM(workhrs)
        FOR eNAME IN ('JONES', 'ALLEN')
      )
/

输出:

   'JONES'    'ALLEN'
---------- ----------
       3.6       7.32


文章来源: Oracle based PIVOT with multiple columns group