2017-06-29 61 views
0

我有兩個無關的查詢。我需要從第一個查詢中選擇其列值不包含任何從另一個查詢返回的值的記錄。請建議一種方法來做到這一點。如何選擇記錄的值與Oracle中另一個查詢中的字符串列表不匹配?

讓我們說,第一個查詢返回這些記錄:

abc_123_xyz 
def_456_hij 
lmn_opq 
rst_uvw 

讓我們說,第二個查詢返回這些記錄:

123 
456 

預期的結果是:

lmn_opq 
rst_uvw 

我寫了一個匹配結果的查詢,它工作正常。但是當我添加NOT LIKE條件時,它失敗。請幫忙!

select o.name 
from (select pattern from PATTERN) p, 
     objects o 
where o.name like '%'||p.pattern||'%'; 

假設模式表返回123,456,它正確的值abc_123_xyz, def_456_hij匹配。但是,如果我使用NOT LIKE條件執行上述查詢,則無法僅返回其他兩條記錄。相反,它會返回所有四個值。這裏有什麼問題?

回答

2

與NOT LIKE將返回所有行,它會返回不TWICE匹配任何行查詢。

您正在加入這兩個表,這意味着您將爲第一個表中的每行和第二個表中的一行中的每個組合獲取輸出行。共8行(4 * 2)。

然後只有兩個這些行被拒絕的WHERE過濾器 - 一行,包含,被拒絕的條件NOT LIKE ... 123 ...(但它仍然包括其他時間,因爲它確實符合條件NOT LIKE ... 456 ...)。

你想要的是一個SEMI-JOIN:你需要一個表中的所有行(只計算一次!),它們與第二個表中的任何內容都不匹配。在你寫的一個連接中,如果第一個表中的一行不匹配一個模式,它將被包含在輸出中,即使它與另一個模式匹配。

你需要的是這樣的:

select name 
from objects o 
where not exists (select pattern from p where o.name like '%' || pattern || '%') 
; 
0

你可以使用一個左連接和

select o.name 
    from objects o 
    left join PATTERN p on o.name like '%'||p.pattern||'%' 
    where p.pattern is null ; 
相關問題