У меня есть данные, что выглядит следующим образом:Ссылка на родительские столбцы в 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