2012-04-11 17 views
5

Usando la base de datos Oracle 11G (no R2), necesitamos crear informes que muestren a qué Comité de Liderazgo pertenece la estructura de informes de un individuo.Oracle 11g CREAR VISTA utilizando CONNECT BY y varias tablas

En un nivel alto, determinamos la presencia de un individuo en el tablero localizando la identificación del empleado en table board_members.

La tabla board_members tiene una ID de posición que se puede usar para acceder a board_positions, y desde allí podemos determinar si el puesto está en el comité de liderazgo. (Muestras abajo.)

Para cualquier empleado que esté en el comité de liderazgo, su propia identificación representará a BOARD_LEAD.

Para cualquier otro empleado, el valor report_to se repite hasta que se identifique a un miembro del Comité de Liderazgo, y la ID de esa persona será BOARD_LEAD.

Nuestro personal de alto nivel tiene report_to igual a su propio empl_id, en lugar del NULL más común.

Para demostrar esto con suerte, he configurado las tablas de muestra, los datos de muestra y muestra el resultado deseado a continuación.

Estoy tratando de entender cómo crear una VISTA que proporcione dicha información para Equivalencia a tiempo completo y otras necesidades de informes. Estoy convencido de que CONNECT BY se verá involucrado, pero la documentación de Oracle me resulta confusa y no he encontrado ejemplos que incluyan varias tablas como esta. (Me temo que hay una buena razón para esta falta de ejemplo.)

¿Es posible escribir una vista así en Oracle 11g (no R2) en lugar de una tabla intermedia que debe actualizarse con cada cambio de posición?

Create table board_positions /* If board_position = 'LDRSHPCOMM' this is a top position */ 
(member_id varchar(6),board_position varchar(18)); 

Create table board_members 
(empl_id varchar(6), member_id varchar(6)); 

Create table emp 
(empl_id varchar(6),ename varchar(32),report_to varchar(6)); 

Insert into board_positions values('CEO','LDRSHPCOMM'); 
Insert into board_positions Values('COO','LDRSHPCOMM'); 
Insert into board_positions Values('CFO','LDRSHPCOMM'); 
Insert into board_positions Values('CIO','LDRSHPCOMM'); 
Insert into board_positions values('WANABE','NEWBIE'); 

Insert into emp ('TOPDOG','Big Guy','TOPDOG'); 
Insert into emp ('WALLET','Money Bags','TOPDOG'); 
Insert into emp ('OPSGUY','Meikut Work','TOPDOG'); 
Insert into emp ('INFGUY','Comp U Turk','TOPDOG'); 
Insert into emp ('HITECH','Number 2','INFGUY'); 
Insert into emp ('LOTECH','Number 3','HITECH'); 
Insert into emp ('PROGMR','Nameless Blameless','LOTECH'); 
insert into emp ('FLUNKY','Ida Dunnit','PROGMR'); 

Insert into board_members ('TOPDOG','CEO'); 
Insert into board_members ('WALLET','CFO'); 
Insert into board_members ('OPSGUY','COO'); 
Insert into board_members ('INFGUY','CIO'); 
Insert into board_members ('HITECH','WANABE'); /* Board position not on the leadership committee */ 

usando algo como:

CREATE VIEW LEADER_VIEW AS 
    WITH T1 AS (SELECT e.empl_id, (something) as board_lead 
       , (something) as board_lead_pos 
      FROM emp e 
      LEFT OUTER JOIN board_members bm 
         ON bm.empl_id = e.empl_id 
      LEFT OUTER JOIN board_positions bp 
         on bp.member_id = bm.member_id 
      ... 
      CONNECT BY PRIOR empl_id = report_to 
      START WITH empl_id = report_to 
      ) 
    SELECT * FROM T1 

(Pero sé que hay mucho más a él que esto!)

ejemplo de salida deseado. . .

TOPDOG   TOPDOG CEO (Because self is on LDRSHPCOMM) 
WALLET   WALLET CFO (Because self is on LDRSHPCOMM) 
OPSGUY   OPSGUY COO (Because self is on LDRSHPCOMM) 
INFGUY   INFGUY CIO (Because self is on LDRSHPCOMM) 
HITECH   INFGUY CIO (Because REPORTTO is on LDRSHPCOMM) 
LOTECH   INFGUY CIO (Because REPORTTO->REPORTTO is on LDRSHPCOMM) 
PROGMR   INFGUY CIO (REPORTTO->REPORTTO->REPORTTO is on LDRSHPCOMM) 
FLUNKY   INFGUY CIO (You know by now.) 

Respuesta

5

se podría hacer algo como esto:

SQL> SELECT * 
    2 FROM (SELECT empl_id, ename, report_to, 
    3     member_id, board_position, 
    4     MAX(lvl) over(PARTITION BY empl_id) maxlvl, lvl 
    5    FROM (SELECT connect_by_root(e.empl_id) empl_id, 
    6       connect_by_root(e.ename) ename, 
    7       bm.empl_id report_to, 
    8       LEVEL lvl, bp.* 
    9      FROM emp e 
10      LEFT JOIN board_members bm 
11        ON e.empl_id = bm.empl_id 
12      LEFT JOIN board_positions bp 
13        ON bm.member_id = bp.member_id 
14     CONNECT BY NOCYCLE e.empl_id = PRIOR e.report_to 
15       AND (PRIOR bp.board_position IS NULL 
16        OR PRIOR bp.board_position != 'LDRSHPCOMM'))) 
17 WHERE lvl = maxlvl; 

EMPL_ID ENAME       REPORT_TO MEMBER_ID BOARD_POSITION  
------- -------------------------------- --------- --------- ------------------ 
FLUNKY Ida Dunnit      INFGUY CIO  LDRSHPCOMM   
HITECH Number 2       INFGUY CIO  LDRSHPCOMM   
INFGUY Comp U Turk      INFGUY CIO  LDRSHPCOMM   
LOTECH Number 3       INFGUY CIO  LDRSHPCOMM   
OPSGUY Meikut Work      OPSGUY COO  LDRSHPCOMM   
PROGMR Nameless Blameless    INFGUY CIO  LDRSHPCOMM   
TOPDOG Big Guy       TOPDOG CEO  LDRSHPCOMM   
WALLET Money Bags      WALLET CFO  LDRSHPCOMM  

tengo ninguna cláusula START WITH porque quiero iniciar la consulta jerárquica para todos los empleados. Para cada empleado recorro los datos jerárquicos hasta que encuentro un administrador que es miembro de la junta en el comité de liderazgo (cláusula CONNECT BY).

Las consultas externas filtran las líneas correspondientes.

Cuestiones relacionadas