Connect By Prior игнорировать ребенка без родителей - PullRequest
0 голосов
/ 28 августа 2018

Я пытался использовать решение из этого исходного поста как мне опустить узлы без родительского элемента в иерархическом (соединяющемся) запросе оракула? . Тем не менее, я не могу решить свою проблему до сих пор (если я что-то упустил, используя это решение). В этом примере он по-прежнему отображает иерархию Emp Id 2 GM и его дочерних детей (который более активен) и Emp Id 3 PRJMGR и его детей, которые больше не являются PRJMGR, а теперь GM.

Я построил это, используя liveql.oracle.com, если кому-то нужно место, где можно поиграть / поиграть с примером:

DROP TABLE EMPLOYEE;
DROP TABLE EMPLOYEE_ASSIGNMENT;
DROP TABLE COMPANY_STRUCTURE_POSITION;
CREATE TABLE EMPLOYEE (EMPLOYEE_ID VARCHAR2(15 CHAR));
CREATE TABLE EMPLOYEE_ASSIGNMENT (EMPLOYEE_ID VARCHAR(15 CHAR),
                                  POSITION_CODE VARCHAR2(10 CHAR),
                                  VALID_FROM DATE,
                                  VALID_TO DATE);
CREATE TABLE COMPANY_STRUCTURE_POSITION (POSITION_CODE VARCHAR2(10 CHAR),
                                         SUPERVISOR_POSITION_CODE VARCHAR2(10 CHAR));
INSERT INTO EMPLOYEE VALUES ('1');
INSERT INTO EMPLOYEE VALUES ('2');
INSERT INTO EMPLOYEE VALUES ('3');
INSERT INTO EMPLOYEE VALUES ('4');
INSERT INTO EMPLOYEE VALUES ('5');          
INSERT INTO EMPLOYEE VALUES ('6');
INSERT INTO EMPLOYEE VALUES ('7');
INSERT INTO EMPLOYEE_ASSIGNMENT VALUES ('1', 'CEO', '01-JAN-18', '31-DEC-18');
INSERT INTO EMPLOYEE_ASSIGNMENT VALUES ('2', 'GM', '01-JAN-18', '30-JUN-18');
INSERT INTO EMPLOYEE_ASSIGNMENT VALUES ('3', 'GM', '01-JUL-18', '31-DEC-18');
INSERT INTO EMPLOYEE_ASSIGNMENT VALUES ('3', 'PRJMGR', '01-JAN-18', '30-JUN-18');
INSERT INTO EMPLOYEE_ASSIGNMENT VALUES ('4', 'PRJMGR', '01-JUL-18', '31-DEC-18');
INSERT INTO EMPLOYEE_ASSIGNMENT VALUES ('5', 'HR', '01-JAN-18', '31-DEC-18');
INSERT INTO EMPLOYEE_ASSIGNMENT VALUES ('6', 'PNT', '01-JAN-18', '31-DEC-18');
INSERT INTO EMPLOYEE_ASSIGNMENT VALUES ('7', 'WLD', '01-JAN-18', '31-DEC-18');
INSERT INTO COMPANY_STRUCTURE_POSITION VALUES ('CEO', '*');
INSERT INTO COMPANY_STRUCTURE_POSITION VALUES ('GM', 'CEO');
INSERT INTO COMPANY_STRUCTURE_POSITION VALUES ('PRJMGR', 'GM');
INSERT INTO COMPANY_STRUCTURE_POSITION VALUES ('HR', 'CEO');
INSERT INTO COMPANY_STRUCTURE_POSITION VALUES ('PNT', 'PRJMGR');
INSERT INTO COMPANY_STRUCTURE_POSITION VALUES ('WLD', 'PRJMGR');
SELECT sys_connect_by_path(e.employee_id, '->') EMPLOYEE_PATH, 
       sys_connect_by_path(csp.position_code, '->') POSITION_CODE_PATH, 
       level,  
       e.*, 
       ea.*, 
       csp.* 
FROM employee e 
INNER JOIN employee_assignment ea ON ea.employee_id = e.employee_id 
INNER JOIN company_structure_position csp ON csp.position_code = ea.position_code 
WHERE ea.valid_from <= TRUNC(sysdate) 
AND ea.valid_to >= TRUNC(sysdate) 
START WITH csp.supervisor_position_code = '*' 
AND ea.valid_from <= TRUNC(sysdate) 
AND ea.valid_to >= TRUNC(sysdate) 
CONNECT BY PRIOR csp.position_code = csp.supervisor_position_code

Результирующий SQL:

| EMPLOYEE_PATH | POSITION_CODE_PATH    | LEVEL | EMP_ID | EMP_ID | POS_CODE | VALID_FROM | VALID_TO  | POS_CODE | SUP_POS_CODE |
---------------------------------------------------------------------------------------------------------------------------------
| ->1           |->CEO                  |  1    |  1     |  1     |  CEO     | 01-JAN-18  | 31-DEC-18 | CEO      | *            |
| ->1->2->3->6  |->CEO->GM->PRJMGR->PNT |  4    |  6     |  6     |  PNT     | 01-JAN-18  | 31-DEC-18 | PNT      | PRJMGR       |
| ->1->2->3->7  |->CEO->GM->PRJMGR->WLD |  4    |  7     |  7     |  WLD     | 01-JAN-18  | 31-DEC-18 | WLD      | PRJMGR       |
| ->1->2->4     |->CEO->GM->PRJMGR      |  3    |  4     |  4     |  PRJMGR  | 01-JUL-18  | 31-DEC-18 | PRJMGR   | GM           |
| ->1->2->4->6  |->CEO->GM->PRJMGR->PNT |  4    |  6     |  6     |  PNT     | 01-JAN-18  | 31-DEC-18 | PNT      | PRJMGR       |
| ->1->2->4->7  |->CEO->GM->PRJMGR->WLD |  4    |  7     |  7     |  WLD     | 01-JAN-18  | 31-DEC-18 | WLD      | PRJMGR       |
| ->1->3        |->CEO->GM              |  2    |  3     |  3     |  GM      | 01-JUL-18  | 31-DEC-18 | GM       | CEO          |
| ->1->3->3->6  |->CEO->GM->PRJMGR->PNT |  4    |  6     |  6     |  PNT     | 01-JAN-18  | 31-DEC-18 | PNT      | PRJMGR       |
| ->1->3->3->7  |->CEO->GM->PRJMGR->WLD |  4    |  7     |  7     |  WLD     | 01-JAN-18  | 31-DEC-18 | WLD      | PRJMGR       |
| ->1->3->4     |->CEO->GM->PRJMGR      |  3    |  4     |  4     |  PRJMGR  | 01-JUL-18  | 31-DEC-18 | PRJMGR   | GM           | 
| ->1->3->4->6  |->CEO->GM->PRJMGR->PNT |  4    |  6     |  6     |  PNT     | 01-JAN-18  | 31-DEC-18 | PNT      | PRJMGR       |
| ->1->3->4->7  |->CEO->GM->PRJMGR->WLD |  4    |  7     |  7     |  WLD     | 01-JAN-18  | 31-DEC-18 | WLD      | PRJMGR       |
| ->1->5        |->CEO->HR              |  2    |  5     |  5     |  HR      | 01-JAN-18  | 31-DEC-18 | HR       | CEO          |  

Спасибо за совет.

1 Ответ

0 голосов
/ 28 августа 2018

Включите условие в предложение CONNECT BY, чтобы не подключаться через неактивные узлы. Как это:

CONNECT BY PRIOR csp.position_code = csp.supervisor_position_code
AND ea.valid_from <= TRUNC(sysdate) 
AND ea.valid_to >= TRUNC(sysdate) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...