基于Oracle的PIVOT具有多个列组 [英] Oracle based PIVOT with multiple columns group

查看:2874
本文介绍了基于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

效率D:

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 和< c> workhrs ,然后转动 RM_ROOM RM_SCR

The following query is generating below output but I need to group employees and sum workhrs and then pivot RM_ROOM and RM_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         
)

电流输出: / strong>

Current Output:

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


推荐答案

你正在以一个固定值,字符串字面值'RM'进行循环,所以你真的没有做任何有用的枢轴 - 输出是相同的,自己运行'pivot_data'查询:

You are pivoting on a fixed value, the string literal 'RM', so you're really not doing anything useful in the pivot - the output is the same as you'd get from running the 'pivot_data' query on its own:

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值的排名(并使用现代连接语法),您将获得:

You want the aggregate workhrs for each employee, and a pivot of the rooms they sold. If you change that query to get the analytic sum of workhrs and a ranking of the room/scr values (and using modern join syntax) you get:

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 号码:

You can then pivot on that generated rnk number:

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_room 3_scr 。你不能避免这种情况,除非你得到一个XML结果或动态生成查询。

You need to know the maximum number of rooms any employee may have - i.e. the highest rnk could ever be - and include all of those in the in clause. Which means you're likely to end up with empty columns, as in this example where there is no data for 3_room or 3_scr. You can't avoid that though, unless you get an XML result or generate the query dynamically.

这篇关于基于Oracle的PIVOT具有多个列组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆