Иерархические данные в Oracle SQL - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть tbl_parent, как это в Oracle SQL, примеры данных приведены ниже:

 Id(primary key)   parentid   childid

  1                 1           2
  2                 1           3
  3                 2           1
  4                 3           1  -- This row is wrong

В приведенной выше таблице некоторые строки вставлены неправильно, например, если parent_id 1 имеет child_id 3тогда parent_id 3 не должно иметь child_id 1, так как 3 уже является дочерним по отношению к 1, поэтому я не могу быть родительским, у меня более 5000 строк и я хочу найти эти неправильные строки, пожалуйста, помогите?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

В основном вы ищете циклов в своей таблице.

Функциональность Oracle для идентификации циклов в иерархическом запросе:

CONNECT BY NOCYCLE и CONNECT_BY_ISCYCLE

В этом запросе отображаются все узлы, ведущие к циклу - столбец is_Cycle = 1

select tbl.* ,
CONNECT_BY_ISCYCLE  is_Cycle, 
SYS_CONNECT_BY_PATH(childid, '/') path
from tbl
CONNECT BY NOCYCLE PRIOR childid = parentid

Для ваших данных результат равен

  PARENTID    CHILDID   IS_CYCLE PATH     
---------- ---------- ---------- ----------
         1          2          0 /2         
         2          1          1 /2/1       
         1          3          1 /2/1/3     
         1          3          0 /3         
         3          1          1 /3/1       
         1          2          1 /3/1/2     
         2          1          0 /1         
         1          2          1 /1/2       
         1          3          1 /1/3       
         3          1          0 /1         
         1          2          1 /1/2       
         1          3          1 /1/3 

Примечаниекаждый цикл распознается в нескольких местах, поэтому вы получаете избыточные данные.

Преимущество этого метода в том, что он работает и для более длинных циклов (где простой подход GROUP BY не работает).

Пример для цикла длиной 3:

create table tbl as
select 1 parentid, 2   childid from dual union all
select 2 parentid, 3   childid from dual union all
select 3 parentid, 1   childid from dual;

  PARENTID    CHILDID   IS_CYCLE PATH     
---------- ---------- ---------- ----------
         1          2          0 /2         
         2          3          0 /2/3       
         3          1          1 /2/3/1     
         2          3          0 /3         
         3          1          0 /3/1       
         1          2          1 /3/1/2     
         3          1          0 /1         
         1          2          0 /1/2       
         2          3          1 /1/2/3 
0 голосов
/ 27 февраля 2019
Функции

greatest и least могут использоваться как

select least(parentid,childid) as least_par_chi_id,
       greatest(parentid,childid) as greatest_par_chi_id
  from tab
 group by greatest(parentid,childid), least(parentid,childid)
having count(*)>1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...