2011-12-01 52 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")