2015-09-13 100 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