初学者SQL查询逻辑

时间:2015-09-13 17:54:38

标签: mysql sql querying

我有两张桌子:一张叫做喜欢喝酒的人和他们喜欢的啤酒。另一个叫卖酒吧名单和他们卖的啤酒。

我在使用特定查询时遇到了困难:

"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酒吧所服务的所有啤酒的饮酒者,而不仅仅是那些人。

非常感谢任何帮助。谢谢。

2 个答案:

答案 0 :(得分:1)

这种类型的查询有时被称为关系分区,对此的常见解决方案是使用双重否定并要求饮用者不存在任何啤酒Bobbys服务不属于他们喜欢的人

跟随它可能有点棘手,但逻辑是合理的。请注意,只要他们喜欢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)

我的想法如下:

  1. 获取Bobbys服务的啤酒
  2. 与这些啤酒一起加入饮酒者,找出哪些饮用者喜欢来自Bobbys的啤酒
  3. 计算每个饮酒者喜欢的啤酒数量(仅限Bobbys服务的那些啤酒),并将那些计数等于Bobbys服务的啤酒总数的饮用者归来。
  4. 这是一个查询:

    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);