Oracle: Làm thế nào để tôi truy vấn một bảng phân cấp?


10

Lý lịch

Đây là để xây dựng một số quan điểm chúng tôi sẽ sử dụng để báo cáo.

Tôi có một bảng các vị trí, các trường chính là "vị trí" và "cha mẹ" .

Cấu trúc mà hai trường này tạo ra, theo cấp độ, nằm dọc theo dòng của Tên công ty -> Tên trường -> Tên tòa nhà -> Tên tầng -> Tên phòng. Tên công ty vẫn giữ nguyên và tên trường vẫn giữ nguyên trong trường hợp này.

Cấu trúc của các vị trí thường trông như thế này:

                                 +-----------+
                                 | Org. Name |
                                 +-----+-----+
                                       |
                                 +-----v-----+
           +--------------------+|Campus Name|+---+--+-------------+
           |                     +--+--------+    |                |
           |                        |             |                |
           |                        |             |                |
        +--+-----+           +------+-+        +--+----+       +---+---+
    +--+| BLDG-01|+--+       | BLDG-02|        |BLDG-03|       |Grounds|
    |   +--------+   |       +--------+        +-------+       +-------+
  +-+------+   +-----+--+
  |Floor-01|   |Basement+-------+
  +-+------+   +--------+       |
    |                           |
    |                           |
    | +----------+      +-------+--+
    +-+Room 1-001|      |Room B-002|
      +----------+      +----------+

Mỗi vị trí liên kết trở lại vị trí mẹ của nó, cuối cùng là tên tổ chức. Hiện tại, chỉ có một tổ chức và một khuôn viên.

Bàn thắng

  • Tôi muốn có thể truy vấn tất cả các vị trí bên dưới bất kỳ vị trí nào ở cấp độ "Tòa nhà". Điều này là để tôi có thể trả về những thứ như có bao nhiêu công việc đã được thực hiện cho bất kỳ vị trí nào trong một tòa nhà nhất định.
  • Tôi muốn có thể xác định vị trí phụ thuộc về tòa nhà nào . Thực chất là ngược lại; Tôi muốn đi từ bất kỳ cấp nào bên dưới cấp tòa nhà và tìm lại xem tòa nhà là gì.
  • Tôi muốn điều này được trong một cái nhìn . Điều đó có nghĩa là, tôi muốn có một bảng cho mọi hạng mục ở cấp độ "tòa nhà", liệt kê tòa nhà ở cột bên trái và tất cả các vị trí có thể DƯỚI tòa nhà đó ở cột bên phải. Bằng cách này, tôi có một danh sách mà tôi có thể truy vấn bất cứ lúc nào để tìm vị trí nào là một phần của tòa nhà đó.

Nỗ lực và làm đúng

Tôi đã cố gắng thực hiện điều này thông qua các quan điểm được xây dựng khủng khiếp, các truy vấn của UNION, v.v. - tất cả đều có vẻ như là một ý tưởng tồi. Tôi biết Oracle sở hữu một cơ chế cho việc này thông qua "CONNECT BY"; Tôi chỉ không chắc làm thế nào để sử dụng nó.


Các nút "gốc" được xác định như thế nào? Là cha mẹ NULLcho họ? Làm thế nào để bạn xác định một "cấp độ xây dựng"?
a_horse_with_no_name

@a_horse_with_no_name về mặt logic, tôi cho rằng cấp độ "tòa nhà" sẽ là bất cứ thứ gì có tên cha mẹ là tên trường, tức là bất cứ thứ gì có cha mẹ của "MAINCAMPUS". Nguồn gốc của tất cả các nút là "COMPANYNAME", là cha mẹ của "MAINCAMPUS" và tất cả các tòa nhà (cộng với "căn cứ") đều có MAINCAMPUS làm cha mẹ.
SeanKilleen

ồ Làm thế nào bạn tạo ra nó !! Google cho "Mô hình điều chỉnh trong SQL", bạn sẽ được thiết lập
srini.venigalla

PS, đối với những người quan tâm đến cách tôi tạo sơ đồ, tôi đã sử dụng một trang web nhỏ tiện lợi có tên asciiflow.com - Tôi là một fan hâm mộ lớn cho các tình huống như thế.
SeanKilleen

Câu trả lời:


4

FrusteratedWithFormsDesigner có hướng đi đúng (+1). Đây là những gì tôi nghĩ rằng bạn đang tìm kiếm cụ thể.

CREATE OR REPLACE VIEW BuildingSubs AS
   SELECT connect_by_root location "Building", location "SubLocation"
   FROM some_table l
   START WITH l.Location IN 
      (
         SELECT location FROM
         (
         SELECT level MyLevel, location FROM some_table 
         START WITH parent IS NULL 
         CONNECT BY PRIOR location=parent
         )
         WHERE MyLevel=3   
      )
   CONNECT BY PRIOR l.location = l.parent;

select * from BuildingSubs; 

Building             SubLocation        
-------------------- --------------------
BLDG-01              BLDG-01              
BLDG-01              Basement             
BLDG-01              Room B-002           
BLDG-01              Floor-01             
BLDG-01              Room 1-001           
BLDG-02              BLDG-02              
BLDG-03              BLDG-03              
Grounds              Grounds              

Quan điểm hoàn thành cả ba mục tiêu. Bạn có thể truy vấn nó cho một tòa nhà để tìm mọi thứ nó chứa và bạn có thể truy vấn nó cho một vị trí phụ để tìm tòa nhà đó ở đâu.

drop table some_table;
create table some_table (Location Varchar2(20), Parent Varchar2(20));

insert into some_table values ('Org. Name',NULL);
insert into some_table values ('MAINCAMPUS','Org. Name');
insert into some_table values ('BLDG-01','MAINCAMPUS');
insert into some_table values ('BLDG-02','MAINCAMPUS');
insert into some_table values ('BLDG-03','MAINCAMPUS');
insert into some_table values ('Grounds','MAINCAMPUS');
insert into some_table values ('Floor-01','BLDG-01');
insert into some_table values ('Basement','BLDG-01');
insert into some_table values ('Room B-002','Basement');
insert into some_table values ('Room 1-001','Floor-01');

Nếu bạn không muốn tính chính tòa nhà là một trong những vị trí phụ, bạn có thể gói truy vấn hiện tại vào một trong những mục loại bỏ trong đó tòa nhà và phân vùng giống nhau.


Leigh, đây chính xác là nó. Cảm ơn bạn vì sự giúp đỡ!
SeanKilleen

9

CONNECT BY là cách chính xác để xử lý dữ liệu được đệ quy tự nhiên.

Tôi không biết bảng của bạn trông như thế nào nhưng có thể giống như:

SELECT *
FROM some_table st
START WITH st.location = 'BLDG-01'
CONNECT BY PRIOR st.location = st.parent;

Điều này sẽ nhận được các nút trong "BLDG-01".

Điều START WITHkhoản là trường hợp cơ sở của bạn.

Một lời giải thích khác (ngoài Oracle mà tôi cho rằng bạn đã đọc và gặp rắc rối với nó, có lẽ nó rất ngắn gọn):

http://www.adp-gmbh.ch/ora/sql/connect_by.html

Cũng thế:

http://psoug.org/reference/connectby.html

Và:

http://www.oradev.com/connect_by.jsp


Cảm ơn vì sự trả lời! Tôi đã nhận được đủ để nhận ra rằng tôi không nghĩ rằng tôi đã đặt câu hỏi của mình tốt. Cấu trúc bảng của tôi có hai cột - "vị trí" và "cha mẹ". Hệ thống phân cấp tạo này được xác định bởi biểu đồ ascii của tôi. Tôi muốn xây dựng một khung nhìn cho thấy, đối với từng vị trí ở cấp độ "tòa nhà", tất cả các vị trí bên dưới nhánh của nó. Mục tiêu của tôi là có thể truy vấn một tòa nhà và có được tất cả các vị trí phụ của nó, hoặc truy vấn một phân vùng và xem nó thuộc về tòa nhà nào, thông qua một khung nhìn (vì vậy không có "tòa nhà-x" nào được xác định trong truy vấn). Mọi sự trợ giúp sẽ rất được trân trọng!
SeanKilleen

2

Tôi không chắc là tôi hiểu câu hỏi của bạn hoàn toàn, nhưng có lẽ đại loại như thế này:

select location, 
       parent,
       sys_connect_by_path(location, '/') as item_list,
       case level
         when 1 then 'building'
         when 2 then 'floor'
         when 3 then 'room'
       end as item_type
from some_table 
start with parent = 'MAINCAMPUS'
connect by prior location = parent;

Điều này sẽ cho bạn thấy thứ bậc cho từng vị trí

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.