SQL Group By等价物

时间:2013-06-26 20:20:54

标签: sql oracle

假装我有cupcake_rating表:

id     |     cupcake      |    delicious_rating
--------------------------------------------
1      |     Strawberry   |    Super Delicious
2      |     Strawberry   |    Mouth Heaven
3      |     Blueberry    |    Godly
4      |     Blueberry    |    Super Delicious

我想找到所有具有'Super Delicious'和'Mouth Heaven'评级的纸杯蛋糕。我觉得使用group by子句可能很容易实现,可能是having

我在想:

select distinct(cupcake) 
  from cupcake_rating 
 group by cupcake 
having delicious_rating in ('Super Delicious', 'Mouth Heaven')

我知道我不能有两个单独的AND语句。我能够通过以下方式实现我的目标:

select distinct(cupcake) 
  from cupcake_rating 
 where cupcake in ( select cupcake 
                      from cupcake_rating 
                     where delicious_rating = 'Super Delicious' ) 
   and cupcake in ( select cupcake 
                      from cupcake_rating 
                     where delicious_rating = 'Mouth Heaven' )

这不会令人满意,因为一旦我添加了我想要的第三种评级,查询将花费数小时(有很多蛋糕评级)。

3 个答案:

答案 0 :(得分:7)

你是对的,你可以使用HAVING子句;也没有必要使用自联接。

你只想要一个有两个等级的蛋糕,所以限制这两个等级,然后检查DISTINCT的等级数是否等于两个:

select cupcake
  from cupcake_rating
 where delicious_rating in ('Super Delicious', 'Mouth Heaven')
 group by cupcake
having count(distinct delicious_rating) = 2

SQL Fiddle

这更易于扩展,因为您不需要为每个美味的评级进行新的自我加入,您只需要检查您是否拥有所需的数字。

答案 1 :(得分:3)

您可以在cupcake上将所有“超级美味”评级加入“Mouth Heaven”评级。通过这种方式,您可以找到所有同时具有“Super Delicious”和“Mouth Heaven”评级的纸杯蛋糕。

SELECT DISTINCT cr.cupcake
FROM cupcake_rating cr
JOIN cupcake_rating cr2
    ON cr.cupcake = cr2.cupcake
WHERE cr.delicious_rating = 'Super Delicious'
    AND cr2.delicious_rating = 'Mouth Heaven'

答案 2 :(得分:1)

I want to find all the cupcakes that have a 'Super Delicious' AND 'Mouth Heaven' rating

我理解上述要求意味着蛋糕必须达到每一个等级,而不仅仅是一个或另一个。换句话说,如果每个人将蛋糕评为Mouth Heaven,则不符合条件。

          select distinct cupcake from cupcake_ratings A where rating = 'super'
          inner join
          (
           select distinct cupcake from cupcake_ratings where rating = 'heaven'
          ) x
          on A.cupcake = x.cupcake

获取两个评级的蛋糕列表。

P.S。如果你有CUPCAKES表,你可以用EXISTS优化它:

         select cupcake from cupcakes
         where exists
         (
            select cupcake from ratings where rating = 'super'
            and ratings.cupcake = cupcakes.cupcake
         )

         and exists
         (
            select cupcake from ratings where rating = 'heaven'
            and ratings.cupcake = cupcakes.cupcake
         )