2011-12-01 41 views
2

我有一個名爲foobar的表,其中列namelocation。我想用SQL來獲取去過紐約但還沒去過舊金山的所有人的姓名。簡單SQL GROUP BY

到目前爲止有:

select name 
    from foobar 
    where location = "New York" and location != "San Francisco" 
group by name 
+0

我認爲每行是一個名稱的位置的訪問。所以如果我去了紐約和SF,那麼會有兩個DaveShaw's,每個位置都有一個?表格數據的一個樣本可能有助於解決這個問題。 – DaveShaw

回答

7
SELECT f.name 
    FROM foobar f 
    WHERE f.location = 'New York' 
     AND NOT EXISTS(SELECT NULL 
          FROM foobar f2 
          WHERE f2.name = f.name 
           AND f2.location = 'San Francisco') 

你也可以用左這樣做JOIN:

SELECT f.name 
    FROM foobar f 
     LEFT JOIN foobar f2 
      ON f.name = f2.name 
       AND f2.location = 'San Francisco' 
    WHERE f.location = 'New York' 
     AND f2.name IS NULL 
+0

沒有酷的羣體...你贏了 – John

5
select name 
from foobar 
where location = "New York" 
and name not in (select name 
from foobar 
where location = "San Francisco") 
0

在這種情況下,SQL 「不存在」 查詢進來便利。看看下面的查詢:

select f1.name 
from foobar as f1 
where f1.location = "New York" 
and not exists 
    (select f2.name 
    from foobar as f2 
    where f1.name= f2.name 
    and location = "San Francisco") 

爲了更好的理解,讓我們把這個查詢分解成更小的部分。

部分-1: 讓我們說,這是QUERY1

select f1.name 
    from foobar as f1 
    where f1.location = "New York" 

這個簡單的選擇查詢將顯示所有已訪問紐約的名字。就那麼簡單!

部分-2: 讓我們說,這是QUERY2

select f2.name 
    from foobar as f2 
    where f2.location = "San Francisco" 

這是將顯示所有已訪問過舊金山的名字另一種簡單的選擇查詢。

現在我們需要實現的是,我們需要訪問紐約的那些人的名字,以及去過舊金山的名字。現在可能發生一個人訪問了紐約和舊金山,因此我們正在消除這些人。我們只想要紐約遊客。所以我們實際上是從QUERY1丟棄QUERY2的結果,結合這樣的:

query1 
    and not exists 
    (query2 + where f1.name = f2.name) 

,或者

select f1.name 
from foobar as f1 
where f1.location = "New York" 
and not exists 
(select f2.name 
    from foobar as f2 
    where f1.name = f2.name 
    and f2.location = "San Francisco")