2015-04-12 2 views
3

Я пытаюсь создать организационную структуру, используя функциональность LEVEL в Oracle11g.Сортировка с уровнем в Oracle11g

У меня есть следующий запрос:

SELECT 
    level, 
    lpad(' ', 3 * (level - 1)) || em.empno || ' : ' || em.fname || ' ' || em.lname "Employee", 
    em.position                 "Position", 
    outno || ': ' || ou.street || ' ' || ou.city || ' ' || ou.zipcode    "Outlet", 
    count(DISTINCT fa.reportnum)             "# of Fault Reports" 
FROM employee em 
    INNER JOIN outlet ou USING (outno) 
    LEFT JOIN faultreport fa ON fa.empno = em.empno AND fa.datechecked > (SYSDATE - 91) 
START WITH em.empno = 30012 
CONNECT BY PRIOR em.empno = em.supervisorno 
GROUP BY level, 
    em.empno, em.fname, em.lname, em.position, 
    outno, ou.street, ou.city, ou.zipcode; 

Который дает мне следующий вывод:

LEVEL Employee       Position    Outlet       # of Fault Reports 
----- --------------------------------- -------------------- ------------------------------ ------------------ 
    1 30012 : Moreno Bale    Owner    119: Forrest Adelaide 5005      0 
    2 45611 : Annah Marlek   Area_Manager   112: Beauford Port Cambia 5001     0 
    2 48900 : Geoff Hanna   Area_Manager   118: Icecream Iyanee 5008      0 
    3  23490 : Abel Cole   Admin_Assistant  116: Huntington Banshee 5007     0 
    3  31459 : Chris Boss   Admin_Assistant  119: Forrest Adelaide 5005      0 
    3  60021 : Beau Rueford  Admin_Assistant  111: Junlee Caprice 5009      0 
    3  67823 : Jess Fred   Head_Mechanic  114: Elephant Ocupus 5004      0 
    4   55601 : Kabil Malla  Mechanic    115: Dundee Eeyrie 5003       1 
    4   55602 : Harry Potter  Mechanic    111: Junlee Caprice 5009      5 
    4   60020 : Maria Marbosa Sales_Rep   113: Cathany Zeus 5002       0 
    4   77689 : Javier Martin Sales_Rep   112: Beauford Port Cambia 5001     0 

11 rows selected. 

Однако, когда я вижу таблицу, это точное соотношение:

Employee Manager 
    30012 - 
    48900 30012 
    45611 30012 
    23490 45611 
    31459 48900 
    67823 48900 
    55602 67823 
    55601 67823 
    60021 48900 
    77689 60021 
    60020 60021 

Как реализовать это в Oracle, чтобы у меня был следующий вывод:

LEVEL Employee       Position    Outlet       # of Fault Reports 
----- --------------------------------- -------------------- ------------------------------ ------------------ 
    1 30012 : Moreno Bale    Owner    119: Forrest Adelaide 5005      0 
    2 45611 : Annah Marlek   Area_Manager   112: Beauford Port Cambia 5001     0 
    3  23490 : Abel Cole   Admin_Assistant  116: Huntington Banshee 5007     0 
    2 48900 : Geoff Hanna   Area_Manager   118: Icecream Iyanee 5008      0 
    3  31459 : Chris Boss   Admin_Assistant  119: Forrest Adelaide 5005      0 
    3  60021 : Beau Rueford  Admin_Assistant  111: Junlee Caprice 5009      0 
    4   60020 : Maria Marbosa Sales_Rep   113: Cathany Zeus 5002       0 
    4   77689 : Javier Martin Sales_Rep   112: Beauford Port Cambia 5001     0 
    3  67823 : Jess Fred   Head_Mechanic  114: Elephant Ocupus 5004      0 
    4   55601 : Kabil Malla  Mechanic    115: Dundee Eeyrie 5003       1 
    4   55602 : Harry Potter  Mechanic    111: Junlee Caprice 5009      5 

11 rows selected. 

Обратите внимание, что если менеджер управляет более чем одним сотрудником, дерево расширяется на основе номера сотрудника.

Спасибо!

ответ

3

Объяснение ваших данных не хватает деталей. В любом случае по запросу, который вы пытались выполнить, и к вашему выпуску с выпуском, я полагаю, что ошибка заключалась в том, что вы пытались выполнить сразу несколько действий: объединение и иерархический запрос.

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

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

В общем случае SQL-обработки заявления оценивает положения запроса в следующем порядке:

  1. ОТ + куда CONNECT BY
  2. ГРУППА ПО
  3. HAVING
  4. ВЫБОР
  5. ORDER BY

Итак, вы должны отделить две вещи грубый подзапрос, который оценивает агрегацию счета перед выполнением этапа иерархического запроса без сортировки вывода.

Вы можете попробовать этот запрос:

SELECT LEVEL, LPAD(' ', 3*(LEVEL - 1)) || empno || ' : ' || EM.fname || ' ' || EM.lname "Employee", 
    EM.position "Position", outno || ': ' || OU.street || ' ' || OU.city || ' ' || OU.zipcode "Outlet", 
    dist_reportnums "# of Fault Reports" 
FROM employee EM 
    JOIN outlet OU using (outno) 
    LEFT JOIN (
      selec empno, COUNT(DISTINCT FA.reportnum) as dist_reportnums 
      from faultreport FA 
      where FA.datechecked > (SYSDATE - 91) 
      GROUP BY empno 
     ) using (empno) 
START WITH empno = 30012 
CONNECT BY PRIOR empno = EM.supervisorno 
+0

Нет, его проблема в том, что ему нужно заказать его результаты. –

+0

Результат запроса будет в том порядке, потому что использование группы по вложенному подзапросу будет сохранять порядок иерархического условия, ведь это ожидаемый. Надеюсь быть ясным! –

+0

... Хорошо, получается, что 'CONNECT BY' будет выполнять некоторые свои заказы. В вашем ответе не очень ясно сказано, что способ записи оригинального заявления переопределяет это. Я рекомендую вам настроить ваш ответ на адрес. –

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