我有看起來像這樣的數據:參考在Oracle CONNECT父列BY分層查詢
KEY1 KEY2 KEY3 LKEY1 LKEY2 LKEY3 FLAG
====== ========= ====== ====== ========= ====== =====
09/10 10000 A1234 09/10 AU00A1234 1
09/10 10000 A1234 09/10 AU000456 A1234 1
09/10 10000 A1234 09/10 AX000001 A1234 1
09/10 AX000001 A1234 09/10 AE000010 A1234 0
09/10 AX000001 A1234 09/10 AE000020 A1234 0
09/10 AX000001 A1234 09/10 AE000030 A1234 0
09/10 10000 A1234 09/10 AX000002 A1234 0
09/10 AX000002 A1234 09/10 AE000040 A1234 0
09/10 10000 A1234 09/10 AU000789 A1234 0
這是分層數據,由此我將查詢針對根複合鍵(在這種情況下09/10 10000 A1234
); FLAG
字段指的是由LKEYx
密鑰標識的「對象」。可以有任何級別的嵌套。 (請注意,KEY1
和KEY3
領域不必是不變的,如上面的例子,只要層次結構將被保留。)
我想檢索哪些葉節點,但如果一片樹葉的父KEY2
是相同的長度或LKEY2
含有X
作爲第二字符,則返回的直接父。在這種情況下,我們還需要標註記錄作爲可選的...所以,這樣的事情:
KEY1 KEY2 KEY3 OPTION FLAG
====== ========= ====== ======= =====
09/10 AU00A1234 0 1
09/10 AU000456 A1234 0 1
09/10 AX000001 A1234 1 1
09/10 AX000002 A1234 1 0
09/10 AU000789 A1234 0 0
我寫了一個查詢,這樣做,但它不是漂亮。此外,它假定所有葉節點都在樹下的同一級別,以便區分可選記錄;但是,這不一定是真的。我的查詢如下:
with queryKeys as (
select '09/10' key1,
'10000' key2,
'A1234' key3,
from dual
),
subTree as (
select tree.key1,
tree.key2,
tree.key3,
tree.lkey1,
tree.lkey2,
tree.lkey3,
tree.flag,
connect_by_isleaf isLeaf,
level thisLevel
from tree,
queryKeys
start with tree.key1 = queryKeys.key1
and tree.key2 = queryKeys.key2
and tree.key3 = queryKeys.key3
connect by tree.key1 = prior tree.lkey1
and tree.key2 = prior tree.lkey2
and tree.key3 = prior tree.lkey3
),
maxTree as (
select max(thisLevel) maxLevel
from subTree
)
select lkey1 key1,
lkey2 key2,
lkey3 key3,
1 - isLeaf option,
flag
from subTree,
maxTree
where (isLeaf = 1 or thisLevel = maxLevel - 1)
and (length(key2) != length(lkey2) or substr(lkey2, 2, 1) != 'X');
原因queryKeys
是因爲它是在一個大的查詢在其他地方使用,並且可以包含多個記錄。 maxTree
部分是問題,超出它的一般怪癖!現在
,該文章的標題的原因是因爲這種查詢可以作出很多更直接,如果我能指的是父母的FLAG
場。我嘗試了JOIN
對待這一想法 - 用自己的相關按鍵加入了樹 - 但是,除非我錯了,這將導致遞歸問題,你會保持不必重複了樹查找正確的父鍵(因爲KEYx
和LKEYx
字段都定義了記錄的完整組合鍵)。
(PS使用Oracle 10gR2中,如果它的確與衆不同。)
美麗!謝謝 :) – Xophmeister