2013-02-27 3 views
2

У меня есть таблица, которая выглядит как (Oracle 11.2.0.2.0):Как для того чтобы достигнуть конкретного иерархического запроса в Oracle

ParentID ID  AllowsEntry 
NULL  A188  N 
A188  1881  Y 
NULL  A189  N 
A189  1891  Y 
1891  189A  Y 

Бизнес-правила позволяют элементам уровня без листьев, чтобы ввод данных, но я нужно сообщить, как если бы они не мне нужно, чтобы иметь возможность запрашивать базу данных для получения вывода, как:

ParentID ID 
NULL  A188 
A188  1881 
NULL  A189 
A189  1891_ 
1891_  189A 

так в основном мне нужно нажать вниз промежуточные ветви, которые позволяют вводить данные на уровне листьев. Новые листья нужно свернуть до переименованной ветви:

Old Tree  New Tree 
A188   A188   -- remains the same, no data entry at this level 
    1881   1881  -- remains the same, data entry allowed at leaf 
A189   A189   -- remains the same, no data entry at this level 
    1891   1891_  -- this is the level that is wrong 
    189A   1891  -- 1891 is push down into a new 1891_ level 
        189A  -- and rolls up into the new level. 
        189B  -- etc. 

Спасибо за помощь

+0

Где '189B' родом? –

+0

Есть еще много значений как на уровне родительской ветви, так и на нижних уровнях листа. Это упрощенный пример. – tayknight

+0

Ваш пример не соответствует первому запросу и последнему. Трудно понять, что вы ожидаете сейчас. –

ответ

0

Я думаю, что вы хотите, чтобы добавить элемент в лист узлов, которые имеют AllowsEnrtry = 'Y'. Элемент узла также должен быть переименован с завершающим подчеркиванием.

Вы можете моделировать измененные данные с UNION ALL и запустить рекурсивный запрос с этой точки зрения:

SQL> WITH DATA AS (
    2  SELECT NULL parentid, 'A188' ID, 'N' allowsEntry FROM dual 
    3  UNION ALL SELECT 'A188', '1881', 'Y' FROM dual 
    4  UNION ALL SELECT NULL , 'A189', 'N' FROM dual 
    5  UNION ALL SELECT 'A189', '1891', 'Y' FROM dual 
    6  UNION ALL SELECT '1891', '189A', 'Y' FROM dual 
    7  UNION ALL SELECT '1891', '189B', 'Y' FROM dual 
    8 ), leaf_also_nodes AS (
    9  SELECT * 
10  FROM DATA 
11  WHERE allowsEntry = 'Y' 
12  AND ID IN (SELECT parentid FROM DATA) 
13 ), data_plus AS (
14  SELECT d.parentid, 
15   d.id, 
16   CASE WHEN l.id IS NOT NULL THEN l.id || '_' ELSE d.id 
17   END display_name 
18  FROM DATA d 
19  LEFT JOIN leaf_also_nodes l ON d.id = l.id 
20  UNION ALL 
21  SELECT ID, NULL, ID FROM leaf_also_nodes 
22 ) 
23 SELECT rpad(' ', (LEVEL - 1) * 2, ' ') || display_name tree 
24 FROM data_plus 
25 START WITH parentid IS NULL 
26 CONNECT BY (PRIOR ID = parentid); 

TREE 
----------------------------------------- 
A188 
    1881 
A189 
    1891_ 
    189A 
    189B 
    1891 
+0

Это круто, и отлично работает. Можно ли написать оператор connect by select, чтобы он возвращал parentid и id с завершающим подчеркиванием для новой родительской ветви? (Пожалуйста, см. Второй оператор select, тот, который имеет символы подчеркивания, в моем первоначальном вопросе). Спасибо. – tayknight

+0

Конечно, добавьте столбец 'PRIOR display_name', чтобы получить измененный' parentid'. –

+0

Ahh. Это круто. Я не знал, что вы можете использовать ключевое слово PRIOR в инструкции select. – tayknight