2017-02-22 141 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子句中,具體而言,僅限那些受PRIOR運算符支配的列。

在你的例子中,儘管看起來這個附加條件(下面)應該沒有效果,但它確實如此。試試吧,你會看到。添加

and PRIOR Row_ID IS NOT NULL 

當然,沒有Row_ID是有史以來空,所以這不會改變的邏輯;但現在將Row_ID的值添加到用於確定循環是否存在的值中,以便您可以獲取所有行。

(注意 - 我剛編輯我的答案改到RowIDRow_ID避免與甲骨文衝突的保留字。)

+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

你如何做遞歸和'開始'部分? (這個問題只顯示一組相關的數據;但如果這是整個表,那麼'從mytable中選擇myrowid就足夠了......) –

+0

確切地說,它只顯示一組相關數據 –

+0

也許我誤解了這個問題,但是我得到它的方式是他想列出他的表中所有與彼此相關的記錄;例如如果它是帶有sourceId = 99和targetId = 100的記錄,則不會被選中。我的錯,如果這不是他想要的,但這是我對' 的解釋,我必須在我的查詢中包含所有這些行,因爲它們全都連接在一起' – Julian