2015-11-09 48 views
0

我試圖用connect by子句寫一個查詢,但我無法處理。層次結構查詢(通過子句連接)

一般來說,我有表:

CREATE TABLE "TESTOWA" (
    "ACCOUNT" VARCHAR2(20 BYTE), 
    "PARENT" VARCHAR2(20 BYTE), 
    "PAYMENT" VARCHAR2(20 BYTE) 
); 

Insert into TESTOWA (ACCOUNT,PARENT,PAYMENT) values ('5436','5436','1'); 
Insert into TESTOWA (ACCOUNT,PARENT,PAYMENT) values ('4576','3457',null); 
Insert into TESTOWA (ACCOUNT,PARENT,PAYMENT) values ('5763','5686','1'); 
Insert into TESTOWA (ACCOUNT,PARENT,PAYMENT) values ('5686','5686',null); 
Insert into TESTOWA (ACCOUNT,PARENT,PAYMENT) values ('3457','5686',null); 

而現在,我想要做的就是找到 每個賬戶可以有父帳戶(父列),其中支付列未填充的賬戶(甚至上級單位)這表明其他帳戶ID。 也許它會更容易,如果我提出它例如:

ACCOUNTID | PARENT | PAYMENT 
----------------------------- 
    5436 | 5436 | 1 
    4576 | 3457 | NULL 
    5763 | 5643 | 1 
    5686 | 5686 | 1 
    3457 | 5686 | NULL 

第一個帳戶是好的 - 支付列被填滿。 其次是不好,因爲是空的 - 但我們可以看到有一個父帳戶,所以現在我們檢查(3457帳戶),並且支付欄再次爲空,但又有一個父帳戶(5686),最後是付款列填充。 因此,對於上述選擇應該不存在什麼 situatios如果表將外觀:

ACCOUNTID | PARENT | PAYMENT 
------------------------------ 
    5436 | 5436 | 1 
    4576 | 3457 | NULL 
    5763 | 5643 | 1 
    5686 | 5686 | NULL 
    3457 | 5686 | NULL 

正如我們所看到的唯一一個變化是空旁邊5686賬戶ID,所以正確的選擇應當出示賬戶:4576, 3457, 5686

回答

1

SQL Fiddle

的Oracle 11g R2架構設置

CREATE TABLE "TESTOWA" ( 
    ACCOUNT NUMBER(4,0), 
    PARENT NUMBER(4,0), 
    PAYMENT NUMBER(1,0) 
); 
Insert into TESTOWA values (5436,5436,1); 
Insert into TESTOWA values (5686,5686,null); 
Insert into TESTOWA values (5763,5686,1); 
Insert into TESTOWA values (3457,5686,1); 
Insert into TESTOWA values (4576,3457,null); 

查詢1

SELECT t.*, 
     CONNECT_BY_ROOT(PAYMENT) AS HAS_PAYED 
FROM TESTOWA t 
START WITH 
     ACCOUNT = PARENT 
OR  PAYMENT = 1 
CONNECT BY 
     NOCYCLE 
     PRIOR ACCOUNT = PARENT 
AND PAYMENT IS NULL 

Results

| ACCOUNT | PARENT | PAYMENT | HAS_PAYED | 
|---------|--------|---------|-----------| 
| 5436 | 5436 |  1 |   1 | 
| 3457 | 5686 |  1 |   1 | 
| 4576 | 3457 | (null) |   1 | 
| 5686 | 5686 | (null) | (null) | 
| 5763 | 5686 |  1 |   1 | 
+0

OMG!我永遠不會猜測如何做到這一點<我需要分析它:)。它工作完美;)謝謝! – maciek2791

+0

START WITH ... PAYMENT = 1'確保所有付費帳戶都位於層級結構的根部,並且'CONNECT BY ... PAYMENT IS NULL'確保付費帳戶不包含在其他層次結構中(因此您不需要不得不擔心重複計數)。 「START WITH」和「CONNECT BY」的其他位僅包含其他(未付費)帳戶。由於每個付費帳戶始終位於層次結構的根部,因此'CONNECT_BY_ROOT(付款)'會告訴您您是否已付款。 – MT0

+0

對,現在我明白了:)再次感謝! :) – maciek2791