2016-09-25 71 views
0

我是新来编写SQL查询和我陷入一些简单的人,我需要找到drinkers who only like bud非单调SQL查询

对于第一种:

SELECT drinker 
FROM likes 
WHERE beer = 'Bud'; 

喜欢(饮酒,啤酒)

我知道上面的查询会返回每个喜欢花蕾的饮酒者,我无法过渡到每个饮者,只有只有喜欢芽。

+2

你不应该问2个不同的问题,在一个职位。有可能第一个问题的答案非常好,但第二个问题的答案并不好,另一个问题反过来也是如此。 – Shadow

+0

@Shadow编辑后 – bkennedy

+0

你只需要确定'HAVING'只有1个喜欢 – Serpiton

回答

1

有很多方法可以解决这个问题。我更喜欢使用与​​子查询的一个,因为在这种情况下,子查询不拉的实际数据,因此它是快速:

SELECT drinker 
FROM likes l1 
WHERE beer = 'Bud' 
AND NOT EXISTS (SELECT 1 FROM likes l2 WHERE l2.drinker=l1.drinker and l2.beer <> "Bud"); 

什么它几乎做的是,它会选择那些饮酒者,像芽和TGEN检查如果那些喜欢别的。如果没有记录与子查询中的条件匹配,则not exists返回true。

+0

它据说生成最好的'explain'计划 – Drew

+0

@shadow'SELECT 1'做了什么?我从来没有遇到这个 – bkennedy

+1

我提供了链接到文档。它在那里解释。 – Shadow

1

为了您的饮酒者,只有像花蕾:

SELECT a.DRINKER 
    FROM (SELECT DRINKER 
      FROM LIKES 
      WHERE BEER = 'BUD') a 
    INNER JOIN (SELECT DRINKER, COUNT(*) 
       FROM LIKES 
       GROUP BY DRINKER 
       HAVING COUNT(*) = 1) b 
    ON b.DRINKER = a.DRINKER 

第一子查询(a)为您的查询其拉回到大家谁喜欢芽。第二个子查询(b)返回所有只喜欢一件事的饮酒者。加入他们会让你只喜欢Bud的饮酒者。

祝你好运。

+0

COUNT(*)'做什么?我的逻辑是找到那些喜欢芽和COUNT(啤酒)= 1但不知道如何结合它的人。另外我不相信我已经被教过'INNER JOIN'或'ON'命令,还有其他方法可以做到这一点吗? – bkennedy

+0

http://docs.oracle.com/cd/B28359_01/server.111/b28286/functions032.htm#i82697 –

+0

不需要嵌套子查询。获得count(*)子查询,然后将其加回到喜欢的表中,并在外部查询中使用where条件。 – Shadow

1

另一种解决方案访问表只有一次,如果这两个最小值和最大值是相同的,只有一个值:

SELECT drinker 
FROM likes 
GROUP BY drinker 
HAVING MIN(beer) = 'Bud' 
    AND MAX(beer) = 'Bud'; 
+0

我喜欢这个解决方案的创意。那么,MIN(啤酒)='Bud'AND MAX(啤酒)='Bud'这两行是如何工作的?我不是很了解min(啤酒)= bud或max(啤酒)= bud。尽管它确实给我提供了正确的数据 – bkennedy

+0

@bkennedy:由于在聚集之后评估HAVING,所以除了'Bud'之外,不能有任何其他值。您可以将最小/最大值添加到选择列表并运行查询,而无需查看基础数据。 – dnoeth