Получение всех детей определенного человека (иерархия на основе деревьев) - PullRequest
0 голосов
/ 12 октября 2018

В настоящее время я пытаюсь получить каждое отношение и потомство к любому конкретному месту дерева.Таблицы следующие:

TABLE ORGANISATION                      TABLE LINKS
| Orga_Name | Code  | DELETED |         | Code  | Dads_Code |  STT  |
| DR        | DR001 |  FALSE  |(root)   | DR001 |   Null    |   OK  |(root no dad snif)
| DSI       | DS001 |  FALSE  |         | DS001 |   DR001   |   OK  |
| DLE       | DL001 |  FALSE  |         | DL001 |   DR001   |   OK  |
| DMP       | DM001 |  FALSE  |         | DM001 |   DS001   |   OK  |
| TRS       | TR001 |  FALSE  |         | TR001 |   DM001   |   OK  |
| TRE       | TE001 |  TRUE   |         | TE001 |   DM001   |   NOK |
| TRC       | TC001 |  FALSE  |         | TE001 |   DM001   |   NOK |

Если какая-либо строка имеет либо DELETED = TRUE, либо STT = NOK, это вообще не должно учитываться.(так же, как TRE и TRC в этом примере)

Идеальный результат будет выглядеть следующим образом:

|  Code  |   PICK-ONE|  Path                     |
|  DS001 |   DR001   |  DS001/DR001              |
|  DL001 |   DR001   |  DL001/DR001              |
|  DM001 |   DR001   |  DM001/DS001/DR001        |
|  TR001 |   DR001   |  TR001/DM001/DS001/DR001  |
|  DM001 |   DS001   |  DM001/DS001              |
|  TR001 |   DS001   |  TR001/DM001/DS001        |
|  TR001 |   DM001   |  DM001/TR001              |

Так что я могу выбрать код в «PICK-ONE» и получить все(прямые и косвенные) дети этого списка.Я пытался использовать CONNECT_BY_ROOT, вот текущий код, который я использую:

    SELECT  Code, 
            CONNECT_BY_ROOT Code,
            LEVEL-1, 
            SYS_CONNECT_BY_PATH(Code, '/') "Path"--,STT

    FROM    (
            SELECT o1.*,a1.STT,o1.DELETED
            FROM ORGANISATION o1
            LEFT JOIN LINKS a1
            ON o1.Code=a1.Code
            AND DELETED = 'FALSE'
            )
    WHERE LEVEL > 0 AND STT like 'OK' 
    CONNECT BY PRIOR Code = Dads_Code;

Я получаю результаты в основном от корня и одного из его (всегда одинаковых) детей.В моем примере результат, который я получу, будет от DS001 и DR001. Некоторые результаты верны. к сожалению, анализ останавливается на 2 максимума уровня , есть несколько дубликатов , а также некоторый путь к себе результаты (с уровнем 0).

Я пытался изменить уровень или путь или изменить некоторые условия, но не могу найти проблему.Я был бы рад, если бы вы могли мне помочь!

1 Ответ

0 голосов
/ 12 октября 2018

Не используйте CONNECT BY, поскольку в данный момент он в основном устарел.Это был хороший способ запрашивать иерархии в те времена, когда не было ничего стандартного.

Использовать рекурсивное общее табличное выражение (aka Recursive CTE), доступное в большинстве баз данных, как часть стандарта SQL.

Например, если вы хотите получить все дочерние элементы DR001, вы можете сделать:

with n (code, dads_code, lvl, path) as (
  select code, dads_code, 1, code from links where code = 'DR001'
  union all
  select l.code, l.dads_code, n.lvl + 1, n.path || '/' || l.code
    from links l
    join n on n.code = l.dads_code
    where l.stt <> 'NOK'
      and not exists (select 1 from organisation o 
                      where o.code = l.code and deleted = 'TRUE')
)
select code, dads_code, lvl, path from n
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...