Oracle: Hiyerarşik bir tabloyu nasıl sorgularım?


10

Arka fon

Bu, raporlama için kullanacağımız bazı görünümlerin oluşturulması içindir.

Konumları bir tablo var, anahtar alanları "konum" ve "üst" .

Bu iki alanın oluşturduğu yapı, seviye olarak, Şirket Adı -> Kampüs Adı -> Bina Adı -> Kat Adı -> Oda Adı satırlarında yer alır. Bu durumda şirket adı ve Kampüs adı aynı kalır.

Konumların yapısı genellikle şöyle görünür:

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

Her konum, en sonunda kuruluş adı olan ana konumuna geri bağlanır. Şu anda sadece bir organizasyon ve bir kampüs var.

Hedefler

  • "Bina" düzeyinde herhangi bir konumun altındaki tüm yerleri sorgulamak istiyorum. Bu nedenle, belirli bir binadaki herhangi bir konum için kaç işgücü gerçekleştirilmiş gibi şeyler döndürebilirim.
  • Hangi alt konumun hangi binaya ait olduğunu belirleyebilmek istiyorum . Aslında tersi; Bina seviyesinin altındaki herhangi bir seviyeden gitmek ve binanın ne olduğuna geri dönmek istiyorum.
  • Bunun bir görüşte olmasını istiyorum . Bu, "yapı" düzeyindeki her öğe için, sol sütundaki binayı ve sağ sütundaki o binanın altındaki tüm olası yerleri listeleyen bir tabloya sahip olmak istiyorum. Bu şekilde hangi konumların hangi binanın bir parçası olduğunu bulmak için her zaman sorgulayabileceğim bir liste olurdu.

Girişimler ve Doğru Yapma

Bunu, kötü bir fikir gibi görünen korkunç bir şekilde oluşturulmuş görüşler, BİRLİĞİ sorguları vb. Yoluyla yapmaya çalıştım. Oracle'ın "CONNECT BY" aracılığıyla bunun için bir mekanizmaya sahip olduğunu biliyorum; Nasıl kullanacağımdan emin değilim.


"Kök" düğümler nasıl tanımlanır? Ebeveyn NULLonlar için mi? Bir "yapı seviyesini" nasıl tanımlarsınız?
a_horse_with_no_name

@a_horse_with_no_name mantıksal olarak, "bina" düzeyi kampüs adı olan bir ebeveyn, yani "MAINCAMPUS" bir ebeveyn ile herhangi bir şey olacağını varsayalım. Tüm düğümlerin kökü, "MAINCAMPUS" ın ebeveyni olan "COMPANYNAME" dir ve tüm binalar (artı "zemin") ana olarak MAINCAMPUS'a sahiptir.
SeanKilleen

Vaov! bunu nasıl yarattın !! "SQL'de
Bitişiklik

PS, diyagramı nasıl yaptığımla ilgilenenler için asciiflow.com adlı şık bir web sitesi kullandım - böyle durumlar için büyük bir hayranıyım.
SeanKilleen

Yanıtlar:


4

FrusteratedWithFormsDesigner doğru yöne (+1) sahiptir. Özellikle aradığınızı düşünüyorum.

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              

Bu görüş üç hedefi de gerçekleştiriyor. İçerdiği her şeyi bulmak için bir bina için sorgulayabilir ve içinde hangi binanın bulunduğunu bulmak için bir alt konum için sorgulayabilirsiniz.

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');

Binanın kendisini alt konumlardan biri olarak saymak istemiyorsanız, mevcut sorguyu bina ve alt konumun aynı olduğu girişleri ortadan kaldırabilirsiniz.


Leigh, aynen öyle. Yardım için teşekkürler!
SeanKilleen

9

CONNECT BY doğal olarak özyinelemeli verileri işlemenin doğru yoludur.

Tablonuzun neye benzediğini bilmiyorum ama belki şöyle bir şey:

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

Bu, "BLDG-01" altındaki düğümleri almalıdır.

START WITHFıkra sizin baz durumdur.

Başka bir açıklama (zaten okuduğunuzu ve sorun yaşadığınızı düşündüğüm Oracle'ın yanı sıra, muhtemelen çok kısa):

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

Ayrıca:

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

Ve:

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


Yanıtınız için teşekkürler! Sorumu iyi ifade ettiğimi düşünmediğimi anlayacak kadar alıyorum. Tablo yapımın iki sütunu var - "konum" ve "üst". Bu oluşturma hiyerarşisi ascii grafiğim tarafından tanımlanır. "Bina" düzeyindeki her bir konum için, şubesinin altındaki tüm konumları gösteren bir görünüm oluşturmak istiyorum. Amacım bir görünümü sorgulamak ve tüm alt konumlarını almak veya bir alt konumu sorgulamak ve hangi binaya ait olduğunu görmek (bir sorguda sabit tanımlanmış "building-x" yok). Herhangi bir yardım büyük mutluluk duyacağız!
SeanKilleen

2

Sorunuzu tamamen anladığımdan emin değilim, ama belki de böyle bir şey:

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;

Bu size her konum için hiyerarşiyi gösterecektir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.