2009-11-05 41 views
1

我不太確定這是叫什麼,但我花了一些時間考慮它,我不知道如何處理它。我確定這很簡單。SQL加入一個'除非'條款

我有兩個表,foo和bar。他們相關的是這樣的:

符表:

| id | name 
-------------- 
| 1 | blah 
| 2 | blarg 
| 3 | blag 

吧檯(巴茲的意思是無關緊要的):

| fooId | baz | 
--------------- 
| 1 | 100 | 
| 1 | 94 | 
| 1 | 27 | 
| 2 | 94 | 
| 3 | 19 | 

每美孚因此,多條。我要選擇,他們有94巴茲,除非他們還擁有了100個巴​​茲所有FOOS因此,在上述情況下,我只想用2

一個id我試圖做選擇美孚東西沿線:

SELECT id FROM foo 
LEFT JOIN bar 
ON foo.id = bar.fooId 
WHERE bar.baz = 94 
AND bar.baz != 100 

但顯然,只有我到目前爲止。我確定這裏可能有一些group by clause,但我不確定它應該是什麼。

在此先感謝!

編輯:如果其他人有這個問題,如@iu提到,這個術語是anti-join

+1

Oracle的優化能夠看到NOT EXISTS,NOT IN和LEFT JOIN/IS NULL語義等價,只要名單值被聲明爲NOT NULL:http://explainextended.com/2009/09/17/not-in-vs-not-exists-vs-left-join-is-null-oracle/ – 2009-11-05 22:37:40

回答

6
select id from foo 
inner join bar b1 on b1.fooId=foo.id and b1.baz=94 
left outer join bar b2 on b2.fooId=foo.id and b2.baz=100 
where b2.fooId is null 

的技術術語,這是一個"anti-join"。正常的內連接是「等連接」。

3
SELECT id 
FROM foo f 
JOIN bar b1 ON f.id = b1.fooId 
LEFT JOIN bar f2 ON f.id = b2.fooId AND b2.baz = 100 
WHERE b1.baz = 94 
AND b2.fooid is null 
0

這可能是這樣的:

SELECT ID從foo的 其中存在(SELECT * FROM酒吧,在那裏foo.id = bar.fooId和bar.baz = 94) 不存在(選擇* from bar where foo.id = bar.fooId and bar.baz = 100)

2
SELECT id FROM foo 
LEFT JOIN bar 
ON foo.id = bar.fooId 
WHERE bar.baz = 94 
AND NOT EXISTS (
    SELECT bar2.fooId FROM bar bar2 
    WHERE bar2.fooId = bar.foodI AND bar2.baz = 100) 

是我該怎麼做的。

2

你可以得到你想要的結果EXISTS和子查詢:

SELECT id 
FROM foo 
WHERE EXISTS (SELECT fooId FROM bar WHERE fooId = foo.id AND baz = 94) 
    AND NOT EXISTS (SELECT fooId FROM bar WHERE fooId = foo.id AND baz = 100)