2015-01-05 151 views
2

表看起來有點像:的Oracle 11g分層查詢需要一定的遺傳數據

create table taco (
    taco_id  int primary key not null, 
    taco_name varchar(255), 
    taco_prntid int, 
    meat_id  int, 
    meat_inht char(1) -- inherit meat 
)   

數據是這樣的:

insert into taco values (1, '1',  null,  1, 'N'); 
insert into taco values (2, '1.1',  1, null, 'Y'); 
insert into taco values (3, '1.1.1',  2, null, 'N'); 
insert into taco values (4, '1.2',  1,  2, 'N'); 
insert into taco values (5, '1.2.1',  4, null, 'Y'); 
insert into taco values (6, '1.1.2',  2, null, 'Y'); 

或...

- 1  has a meat_id=1 
- 1.1 has a meat_id=1 because it inherits from its parent via taco_prntid=1 
- 1.1.1 has a meat_id of null because it does NOT inherit from its parent 
- 1.2 has a meat_id=2 and it does not inherit from its parent 
- 1.2.1 has a meat_id=2 because it does inherit from its parent via taco_prntid=4 
- 1.1.2 has a meat_id=1 because it does inherit from its parent via taco_prntid=2 

現在...我在世界上如何查詢meat_id是什麼每個taco_id?下面是什麼工作,直到我意識到我沒有使用繼承標誌,我的一些數據搞亂了。

select x.taco_id, 
     x.taco_name, 
     to_number(substr(meat_id,instr(rtrim(meat_id), ' ', -1)+1)) as meat_id 

from ( select taco_id, 
        taco_name, 
        level-1 "level", 
        sys_connect_by_path(meat_id, ' ') meat_id 
      from  taco 
      start with taco_prntid is null 
      connect by prior taco_id = taco_prntid 
     ) x   

我可以發佈一些失敗的嘗試來修改上面的查詢,但他們是相當尷尬的失敗。在超出基本範圍之前,我還沒有用過分層查詢,所以我希望有一些關鍵字或概念我不知道應該搜索。


我在底部張貼了一個答案,以表明我最終結束了什麼。我正在接受另一個被接受的答案,因爲他們能夠使我的數據更加清晰,沒有它,我不會得到任何地方。

+0

這是否對你有幫助? http://sqlfiddle.com/#!4/642482/2 –

回答

1

您的內部查詢是正確的。您只需從內部查詢的meat_id列中選擇最右邊的數字,當標誌爲Y時。 我已使用REGEXP_SUBSTR函數獲取最右邊的數字和CASE語句來檢查標誌。

SQL Fiddle

查詢1

select taco_id, 
     taco_name, 
     taco_prntid, 
     case meat_inht 
      when 'N' then meat_id 
      when 'Y' then to_number(regexp_substr(meat_id2,'\d+\s*$')) 
     end meat_id, 
     meat_inht 
from ( select taco_id, 
        taco_name, 
        taco_prntid, 
        meat_id, 
        meat_inht, 
        level-1 "level", 
        sys_connect_by_path(meat_id, ' ') meat_id2 
      from  taco 
      start with taco_prntid is null 
      connect by prior taco_id = taco_prntid 
     ) 
order by 1 

Results

| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT | 
|---------|-----------|-------------|---------|-----------| 
|  1 |   1 |  (null) |  1 |   N | 
|  2 |  1.1 |   1 |  1 |   Y | 
|  3 |  1.1.1 |   2 | (null) |   N | 
|  4 |  1.2 |   1 |  2 |   N | 
|  5 |  1.2.1 |   4 |  2 |   Y | 
|  6 |  1.1.2 |   2 |  1 |   Y | 

查詢2

select taco_id, 
        taco_name, 
        taco_prntid, 
        meat_id, 
        meat_inht, 
        level-1 "level", 
        sys_connect_by_path(meat_id, ' ') meat_id2 
      from  taco 
      start with taco_prntid is null 
      connect by prior taco_id = taco_prntid 

Results

| TACO_ID | TACO_NAME | TACO_PRNTID | MEAT_ID | MEAT_INHT | LEVEL | MEAT_ID2 | 
|---------|-----------|-------------|---------|-----------|-------|----------| 
|  1 |   1 |  (null) |  1 |   N |  0 |  1 | 
|  2 |  1.1 |   1 | (null) |   Y |  1 |  1 | 
|  3 |  1.1.1 |   2 | (null) |   N |  2 |  1 | 
|  6 |  1.1.2 |   2 | (null) |   Y |  2 |  1 | 
|  4 |  1.2 |   1 |  2 |   N |  1 |  1 2 | 
|  5 |  1.2.1 |   4 | (null) |   Y |  2 |  1 2 | 
+0

謝謝soooo多... –

+0

我們錯過了一個案例。但我認爲看到這個後可能很容易處理。有些東西可能有meat_id = 1,那麼孩子繼承,下一個孩子沒有繼承,但有一個空值,下一個孩子然後繼承空值。我需要一種方法來獲取null。所以...我所要做的就是......改變我通過......連接的方式,並使用......空格爲空......並......清理之後。 –

0

這是我已經結束了那麼遠,在接受的答案應用邏輯之後。我還添加了一些其他內容,以便我可以將結果加入我的meat表中。大寫可以優化一點點,但我是這樣查詢的這一部分,所以......它將不得不暫停。

select x.taco_id, 
     x.taco_name, 
     x.taco_prntname, 
     meat_id 

     ,case when to_number(regexp_substr(meat_id,'\d+\s*$'))=0 then null else 
      to_number(regexp_substr(meat_id,'\d+\s*$')) end as meat_id 

from ( select taco_id, 
        taco_name, 
        taco_prntname, 
        level-1 "level", 

        sys_connect_by_path( 
         case when meat_inht='N' then nvl(to_char(meat_id),'0') else '' end 
        ,' ') meat_id 

      from  taco join jobdtl on jobdtl.jobdtl_id=taco.jobdtl_id 
      start with taco_prntid is null 
      connect by prior taco_id = taco_prntid 
     ) x 

(你有沒有想過,當你讀到這樣的問題,真正的模式是什麼呢?很明顯,我不工作的塔科項目。或者它甚至重要,只要一般的關係和概念保存?)