2011-02-23 80 views
3

我有這個表:SQL查詢查找所有可能的路徑

create table testtb (c1 number, c2 number); 
insert into testtb values (1, 100); 
insert into testtb values (2, 100); 
insert into testtb values (3, 100); 
insert into testtb values (3, 101); 
insert into testtb values (4, 101); 
insert into testtb values (5, 102); 
commit; 

我掙扎拿出SQL查詢將返回以下結果時,where子句是這樣的:「C2 = 100」

結果集:

c1 c2 
-- --- 
1 100 
2 100 
3 100 
3 101 
4 101 

原因結果集包含「3101」,是因爲它是通過「3100」到達。和「4,101」相同:可通過 - >「3,101」 - >「3,100」。

更新:此表包含來自相似性加入後的2個不同數據集的標識符。所以這個想法是允許用戶通過任何標識符搜索並顯示兩個數據集之間的所有可能的匹配。這就是爲什麼當用戶搜索「c2 = 100」時,我還想顯示「3,101」和「4,101」來顯示完整匹配圖。

謝謝。

+2

你能解釋一下多一點什麼行代表什麼?爲什麼3,100行將其他兩項添加到結果中? – 2011-02-23 22:01:14

+2

也許給我們你現在擁有的東西,這樣我們就可以看到你想要做的事情。 – 2011-02-23 22:03:11

+0

你在找「CONNECT BY」嗎?是否有限制級數 - 大概至少有2個級別來獲得'4,101'條目。但它不是很清楚你需要什麼...... – 2011-02-23 22:07:29

回答

4
select distinct c1, c2 
from testtb 
connect by nocycle prior c1 = c1 or prior c2 = c2 
start with c2 = 100 
order by c1, c2; 
+0

這就是它!如果你不介意還有一個問題。針對測試表(具有兩列索引)的此查詢的執行計劃顯示「全表掃描」。這是因爲「連接」? – mtim 2011-02-24 02:15:52

+0

是的,它可能與連接有關,我對這些類型的查詢有很多性能問題。我增加了100000行,在C1和C2上建立了索引,並收集了統計數據,而11gR2只使用了C2索引。奇怪的是,通過查詢連接的全表掃描基數估計爲2(!),但是對於簡單的'select countt(*)from testtb',基數估計是完美的。我可以通過添加提示'/ * + dynamic_sampling(testtb,4)* /'來使用兩個索引。 – 2011-02-24 03:16:00

+0

謝謝,我會嘗試使用提示來運行對真實數據的查詢,並查看它是如何發生的。 – mtim 2011-02-24 03:32:31

1

嘗試一個子查詢...從你的初始文章推斷這個,希望它有幫助。

select * from testtbl where c1 in (select c1 from testtbl where c2=100) 

(我是MSSQL人如此道歉,如果這100%不映射到PL-SQL,但你的想法)

編輯: 對不起,我看你也想4101。也許兩個級別的子查詢呢?

select * 
    from testtbl 
    where c2 in 
    (select c2 from testtbl where c1 in (select c1 from testtbl where c2=100)) 
+0

它不返回4,101 – mtim 2011-02-23 22:10:37

+0

是,看到4,101 ...編輯版本工作 – pelazem 2011-02-23 22:13:29

+0

正確,但遞歸級別未知。 – mtim 2011-02-23 22:19:00

3

相同的思路jonearles答案,但使用遞歸子查詢分解:

WITH pathtb(c1,c2) AS 
    (
    SELECT c1,c2 FROM testtb WHERE c2=100 
    UNION ALL 
    SELECT testtb.c1,testtb.c2 FROM 
    testtb JOIN pathtb ON (pathtb.c1=testtb.c1 or pathtb.c2=testtb.c2) 
) CYCLE c1,c2 set cycle TO 1 default 0 
    SELECT DISTINCT c1,c2 FROM pathtb WHERE cycle=0 
    ORDER BY c1,c2 
+0

+1尼斯查詢。它看起來比'connect by'更復雜,但您的查詢更加標準,運行速度快幾倍。 – 2011-02-24 00:05:02

+0

同意,很好的查詢,但Oracle(10/11)克不支持這種語法:( – mtim 2011-02-24 02:11:22