基于Oracle的PIVOT具有多列组

时间:2016-04-02 10:48:34

标签: database oracle pivot

使用下表

生产力:

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

2 个答案:

答案 0 :(得分:2)

你正在使用一个固定值,字符串文字'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结果或动态生成查询,否则无法避免这种情况。

答案 1 :(得分:0)

你所说的毫无意义。你是什​​么意思&#34;枢转RM_ROOM&#34;?所以我不得不猜。我猜你想组织员工和工作总结,然后转动结果。 &#34;输出&#34;你显示似乎是pivot_data,你的子查询的输出。

你的答案只有eNAME,而且每个人都有一个工作小时数。因此,您不需要在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