Это относится немного к моему последним QuestionКак избежать дубликатов с иерархическим запросом
Во всяком случае, у меня есть иерархическая таблица структурированной следующим образом (в реальном, коды всегда будут varchar2 (3), номер только упростить):
Family_code | Parent_Family_Code | ....
1 2
2 4
3 6
4 3
6 null
8 null
9 8
......................
Вывод должен быть:
Family_code | parent_1 | p_2 | p_3 | p_4 | p_5 | .....
1 2 4 3 6 null null.....
2 4 3 6 null null...
3 6 null...
4 3 6 null ...
6 null...
8 null...
9 8 null..
Я придумал решение с использованием connect by
substr()
и connect_by_path
, что приводит к ожидаемому результату, но с дубликатами - не совсем повторяется, но позволяет сказать, что family_code = 1 приводит к результатам (1,2,4,3,6,null..)
и (1,2,4,3,null,null...)
и (1,2,4,null...)
вместо (1,2,4,3,6, null ...) который является полным путем. Это запрос:
SELECT s.family_code,
s.parent_family_code_1,
s.parent_family_code_2,
CASE WHEN length(s.family_path) - (4 * 3 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 3 + 2), 3) ELSE NULL END as parent_family_code_3,
CASE WHEN length(s.family_path) - (4 * 4 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 4 + 2), 3) ELSE NULL END as parent_family_code_4,
CASE WHEN length(s.family_path) - (4 * 5 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 5 + 2), 3) ELSE NULL END as parent_family_code_5,
CASE WHEN length(s.family_path) - (4 * 6 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 6 + 2), 3) ELSE NULL END as parent_family_code_6,
CASE WHEN length(s.family_path) - (4 * 7 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 7 + 2), 3) ELSE NULL END as parent_family_code_7,
CASE WHEN length(s.family_path) - (4 * 8 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 8 + 2), 3) ELSE NULL END as parent_family_code_8,
CASE WHEN length(s.family_path) - (4 * 9 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 9 + 2), 3) ELSE NULL END as parent_family_code_9,
CASE WHEN length(s.family_path) - (4 * 10 + 2) > 0 THEN substr(s.family_path, length(s.family_path) - (4 * 10 + 2), 3) ELSE NULL END as parent_family_code_10
FROM (SELECT t.family_code,
t.parent_family_code as parent_family_code_1,
prior t.parent_family_code as parent_family_code_2,
sys_connect_by_path(t.family_code, ',') as family_path
FROM table t
connect by prior t.family_code = t.parent_family_code) s
можно использовать вспомогательный запрос, чтобы установить, что путем сравнения максимальной длины пути и принимать только это:
SELECT * FROM (
SELECT t.family_code,
t.parent_family_code as parent_family_code_1,
prior t.parent_family_code as parent_family_code_2,
sys_connect_by_path(t.family_code, ',') as family_path
FROM WIZ_PRODUCT_FAMILY_CODES t
connect by prior t.family_code = t.parent_family_code) t
WHERE length(t.family_path) = (SELECT MAX(length(sys_connect_by_path(s.family_code, ','))) FROM WIZ_PRODUCT_FAMILY_CODES s
where s.family_code = t.family_code
connect by prior s.family_code = s.parent_family_code)
Но тогда он стал уродливым и грязным и будет быть трудно поддерживать на этом, когда другой программист будет пытаться работать над этим.
Итак, есть ли лучший/более читаемый способ, взяв только запись пути?
Заранее спасибо.
В иерархическом запросе нет предложения «СТАРТ С». Этот раздел определяет записи, которые являются корневыми узлами иерархии в вашей таблице. Без этого предложения все записи в thable рассматриваются как корневые узлы, а Oracle берет каждую запись один за другим как «root», а для каждого генерирует иерархию. Например, если у вас 1-2-3-4, то без «START WITH col = 1» вы получите в общей сложности 4 иерархии: 1-2-3-4, 2-3-4, 3-4 и 4. Посмотрите мой последний ответ: http://stackoverflow.com/questions/36964508/how-to-get-the-path-of-an-hairsp; -иерархия - есть пункт «НАЧАТЬ С». – krokodilko
В основном, что я хочу, мне нужен путь для каждой записи в таблице, а не только для корней иерархии (посмотрите на мой пример вывода), но я хочу только весь путь каждого из них. @kordirko , И хотя я принял ваш ответ в последнем вопросе, он не дал правильного результата, мне просто нужен другой подход подстроки. – sagi
Трудно диагностировать, не глядя на данные в таблице. Создайте минимальный проверенный пример: http://stackoverflow.com/help/mcve входных данных в таблице (всего несколько записей будет достаточно), вместе с фактическим результатом, сгенерированным запросом, и результатом desiderd для этого примера данных , – krokodilko