Рекурсивный sql-запрос в oracle

#sql #oracle

#sql #Oracle

Вопрос:

Таблица: ID1 и ID2 — это имя столбца

 | ID1   |   ID2 | 
| 4     |     3 |     
| 3     |     2 |   
| 2     |     1 |    
| 7     |     6 |     
| 6     |     5 |    
| 9     |     8 |    
  

Желаемый результат

 | ID1   |   ID2 | 
| 4     |     1 |     
| 7     |     5 |   
| 9     |     8 | 
  

Мне нужно создать рекурсивный sql-запрос для oracle, используя connect by или рекурсивный cte. Не удается найти решение.

Комментарии:

1. Какую версию Oracle вы используете?

2. текущая версия 12.1

Ответ №1:

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

 SQL> with t(id1, id2) as
  2  (select 4,3 from dual
  3  union all select 3,2 from dual
  4  union all select 2,1 from dual
  5  union all select 7,6 from dual
  6  union all select 6,5 from dual
  7  union all select 9,8 from dual)
  8  select connect_by_root id1 id1, id2
  9    from t
 10   where connect_by_isleaf = 1
 11  start with not exists (select null from t t0 where t0.id2 = t.id1)
 12  connect by prior id2 = id1;

       ID1        ID2
---------- ----------
         4          1
         7          5
         9          8
  

Комментарии:

1. Огромное спасибо. У меня это сработало, но я не могу понять это решение

Ответ №2:

Это всего лишь дополнительный ответ без использования иерархических запросов, который удаляет общие элементы из id1 и id2.

      WITH t(id1, id2) 
     AS (SELECT 4, 
                3 
         FROM   dual 
         UNION ALL 
         SELECT 3, 
                2 
         FROM   dual 
         UNION ALL 
         SELECT 2, 
                1 
         FROM   dual 
         UNION ALL 
         SELECT 7, 
                6 
         FROM   dual 
         UNION ALL 
         SELECT 6, 
                5 
         FROM   dual 
         UNION ALL 
         SELECT 9, 
                8 
         FROM   dual), 
     t1 
     AS (SELECT id1 id1, 
                id1 id2 
         FROM   t), 
     t2 
     AS (SELECT id2 id1, 
                id2 id2 
         FROM   t), 
     t3 
     AS (SELECT ROWNUM row_num1, 
                id1 
         FROM   (SELECT ( t.id1 ) id1 
                 FROM   t 
                 WHERE  NOT EXISTS (SELECT NULL 
                                    FROM   t1, 
                                           t2 
                                    WHERE  ( t1.id1 = t2.id1 
                                             AND t1.id2 = t2.id2 ) 
                                           AND ( t.id1 = t1.id1 )) 
                 ORDER  BY t.id1 ASC)), 
     t4 
     AS (SELECT ROWNUM row_num1, 
                id2 
         FROM   (SELECT ( t.id2 ) id2 
                 FROM   t 
                 WHERE  NOT EXISTS (SELECT NULL 
                                    FROM   t1, 
                                           t2 
                                    WHERE  ( t1.id1 = t2.id1 
                                             AND t1.id2 = t2.id2 ) 
                                           AND ( t.id2 = t2.id2 )) 
                 ORDER  BY t.id2 ASC)) 
SELECT a.id1, 
       b.id2 
FROM   t3 a, 
       t4 b 
WHERE  a.row_num1 = b.row_num1 
ORDER  BY id1;