2017-02-22 28 views
0

Допустим, у меня есть следующая таблицаCONNECT BY - ORACLE - позволяет только один Cicle

RowId | SourceId | TargetId 
---------|----------|---------- 
    1 | 1  | 2 
    2 | 2  | 3 
    3 | 2  | 4 
    4 | 4  | 5 
    5 | 5  | 6 
    6 | 6  | 5 

я должен принести все эти строки в моем запросе, так как все они связаны. Однако, когда я делаю это:

SELECT RowId 
FROM MyTable 
START WITH SourceId = 1 
CONNECT BY NOCYCLE PRIOR TargetId = SourceId 

Это не принесет строку с RowId равно 6.

Я думаю, что это из-за NOCYCLE ключевого слова. Но если я его отниму, запрос не работает, так как там есть cicle.

Я хотел задать запрос, который принесет мне все. У вас есть идеи?

+1

'RowID' - не хорошо, это зарезервированное слово ... сделать его' Row_ID'. – mathguy

ответ

3

циклам детектируются на основе значений в столбцах, включенных в предложении CONNECT BY и, в частности, ТОЛЬКО те столбцы, которые подчиняются оператору ПРИОР.

В вашем примере, хотя это кажется дополнительным условием (ниже), не должно иметь никакого эффекта. Просто попробуй, и ты увидишь. Добавить

and PRIOR Row_ID IS NOT NULL 

Конечно, не Row_ID никогда не является пустым, так что это не меняет логику; но теперь значение Row_ID добавляется к значениям, рассмотренным при определении того, существует ли цикл, поэтому вы сможете получить все свои строки.

(Примечание - я просто редактировал свой ответ, чтобы изменить RowID к Row_ID, чтобы избежать конфликта с Oracle зарезервированное слово.)

+0

Действительно, хорошо сказано. Спасибо! –

3

Я только что нашел решение.

SELECT myRowId 
FROM myTable 
START WITH SourceId = 1 
CONNECT BY NOCYCLE PRIOR TargetId = SourceId or TargetId = PRIOR SourceId 

Обмен с вами всем. Благодарю.

+0

Я не согласен. Хотя это может сработать, это не «правильный» ответ. (Конечно, я просто дал другой, и я считаю, что это правильный!) – mathguy

0

Это будет работать. Однако вам действительно не нужен CONNECT BY для чего вы хотите, а не что-то не так с этим.

Вот альтернативный вариант без использования CONNECT BY

select * 
    from test et 
where exists(select 1 
       from test it 
       where et.targetId = it.sourceId OR it.targetId = et.sourceId) 
order by row_id; 

Это в значительной степени применить ту же идею, разработку которой строки указывать друг другу

+0

Как вы делаете рекурсию и часть «начать с»? (Вопрос только показывает одну связанную группу данных, но если бы это была вся таблица, то 'select myrowid from mytable' было бы достаточно ...) –

+0

точно, она отображает только одну связанную группу данных –

+0

Возможно, я неправильно понял вопрос, но как я понял, он хотел перечислить все записи в его таблице, которые связаны друг с другом; например если бы это была запись с исходным кодом = 99 и targetId = 100, он не был бы выбран. Моя вина, если это не то, что он хотел, но это была моя интерпретация ' Мне нужно привести все эти строки в мой запрос, потому что все они связаны. – Julian

 Смежные вопросы

  • Нет связанных вопросов^_^