2012-04-11 50 views
5

Sử dụng cơ sở dữ liệu Oracle 11G (không phải R2), chúng tôi cần tạo báo cáo cho thấy cấu trúc báo cáo Lãnh đạo nào của từng cá nhân.Oracle 11g TẠO XEM bằng cách sử dụng CONNECT BY và nhiều bảng

Ở mức cao, chúng tôi xác định sự hiện diện của một cá nhân trên bảng bằng cách định vị ID nhân viên trong bảng board_members.

Bảng board_members có ID vị trí có thể được sử dụng để truy cập vào các giới hạn trên bo mạch chủ và từ đó chúng tôi có thể xác định xem vị trí có nằm trong ủy ban lãnh đạo hay không. (Các mẫu bên dưới.)

Đối với bất kỳ nhân viên nào trong ủy ban lãnh đạo, ID riêng của anh ấy sẽ đại diện cho BOARD_LEAD.

Đối với bất kỳ nhân viên nào khác, giá trị report_to được đệ trình cho đến khi thành viên Ủy ban lãnh đạo được xác định và ID của người đó sẽ là BOARD_LEAD.

Nhân viên cấp cao nhất của chúng tôi có report_to bằng empl_id của riêng họ, chứ không phải là NULL phổ biến hơn.

Để chứng minh điều này, tôi đã thiết lập các bảng mẫu, dữ liệu mẫu và mẫu đầu ra mong muốn bên dưới.

Tôi đang cố gắng hiểu cách tạo VIEW sẽ cung cấp thông tin như vậy cho Toàn thời gian tương đương và các nhu cầu báo cáo khác. Tôi tin rằng CONNECT BY sẽ được tham gia, nhưng tôi thấy tài liệu Oracle khó hiểu và tôi đã không tìm thấy ví dụ nào bao gồm nhiều bảng như thế này. (Tôi sợ có lý do chính đáng cho việc thiếu ví dụ này.)

Thậm chí có thể viết quan điểm như vậy ở Oracle 11g (không R2) thay vì bảng trung gian phải được cập nhật với từng thay đổi vị trí không?

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 */ 

Sử dụng một cái gì đó như:

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 

(Nhưng tôi biết có nhiều hơn nữa để nó hơn thế này!)

mong muốn ví dụ đầu ra. . .

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.) 

Trả lời

5

Bạn có thể làm một cái gì đó như thế này:

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  

Tôi không có bắt đầu với khoản vì tôi muốn bắt đầu truy vấn thứ bậc cho tất cả nhân viên. Đối với mỗi nhân viên tôi đi qua các dữ liệu phân cấp cho đến khi tôi tìm thấy một người quản lý là thành viên hội đồng quản trị trên ủy ban lãnh đạo (mệnh đề CONNECT BY).

Các truy vấn bên ngoài lọc các dòng có liên quan.

Các vấn đề liên quan