2016-04-02 4 views
0

Используя следующие таблицы,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_ROOM и 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   
) 

Выходной ток:

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 
+0

Некоторые образцы данных были бы хорошими. –

+0

@Tim. Данные в Ouput просто должны преобразовать последнюю строку и группу первых двух столбцов. –

+0

согласился с первым комментарием, вы недостаточно показываете, чтобы получить четкий ответ. Покажите нам структуру и данные ваших 2 таблиц –

ответ

0

Что вы говорите, не имеет никакого смысла. Что вы подразумеваете под «pivot RM_ROOM»? Поэтому я должен угадать. Я предполагаю, что вы хотите группировать сотрудников и суммировать рабочие часы, а затем поворачивать результат. «Вывод», который вы показываете, кажется, является результатом для 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 
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 для каждого сотрудника, d стержень комнат, которые они продали. Если изменить этот запрос, чтобы получить аналитическую сумму 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_room или 3_scr. Вы не можете этого избежать, если только вы не получите результат XML или динамически генерируете запрос.

+0

Мне нужно создать отчет, и мы не можем использовать значения fix в разделе –

+0

@MuhammadMuazzam - вы должны иметь фиксированное значение. Или, по крайней мере, фиксированное количество значений, что и есть здесь. SQL-запрос должен знать, сколько столбцов будет в наборе результатов перед его анализом и выполнением. Вы можете генерировать запрос динамически, но он немного беспорядочен, и все, что обрабатывает запрос, должно иметь дело с разным количеством столбцов. Может быть, ваш инструмент отчетности может игнорировать пустые столбцы или сам свод? –

+0

Хорошо, я буду награждать, если не будет другого лучше, чем это решение, тем временем у меня есть решение построить динамическое предложение, используя PIVOT. –

Смежные вопросы