2015-09-13 104 views
1

我有2个表格:一个叫做喜欢饮酒者和他们喜欢的啤酒列。另一个叫卖出栏的酒吧名称和他们卖的啤酒。初学者SQL查询逻辑

我有一个艰难的时间与特定查询:

"Drinkers who like every beer served by Bobbys" 

我已经通过以下(有瑕疵)SQL查询工作:

Select distinct a.drinker 
from likes a 
where exists 
(
    select * 
    from likes b, sells t 
    where a.drinker = b.drinker 
    and a.beer = t.beer 
    and t.bar = 'Bobbys' 
); 

但这个查询返回谁喜欢一些饮酒者由Bobbys供应啤酒,不是所有的啤酒。只要饮酒者喜欢Bobbys供应的啤酒,它的名字就会被返回,这不是该声明所要求的。

我很难在逻辑上改变这个查询,只包括那些喜欢酒吧Bobbys供应的所有啤酒的饮用者,而不仅仅是一些。

任何帮助将不胜感激。谢谢。

回答

1

这种类型的查询有时称为关系分裂和该一个常见的解决方案是使用一个双否定,并要求饮酒对于其中存在不存在鲍比投放任何啤酒是不间他们喜欢的那些

它可能有点棘手,但逻辑是健全的。请注意,只要喜欢其他啤酒,只要他们喜欢Bobbys所服务的所有东西即可。

select distinct drinker 
from likes l1 
where not exists (
    select * 
    from sells s 
    where bar = 'Bobbys' 
    and not exists (
     select * 
     from likes l2 
     where s.beer = l2.beer 
     and l2.drinker = l1.drinker 
    ) 
); 

Sample SQL Fiddle

1

我的想法是这样的:

  1. 获取由鲍比担任
  2. 啤酒加入饮酒者与那些啤酒,找出哪些饮酒者像鲍比
  3. 啤酒
  4. 计算每位饮酒者喜欢的啤酒数量(仅限Bobbys提供的啤酒),并返回计数等于总数的饮酒者由Bobbys提供的多种啤酒。

下面是一个查询:

with bobbysbeers as (select distinct beer from sells where bar = 'Bobbys') 
select a.drinker 
from likes a, bobbysbeers b 
where a.beer = b.beer 
group by drinker 
having count(distinct a.beer) = (select count(*) from b); 
+0

MySQL不支持公共表表达式,但如果你重写它使用派生表,将工作。 – jpw

+0

好点。我没有意识到这是在MySQL上。 –

+0

请参阅:http://www.sqlfiddle.com/#!9/95fdd9/3 – jpw