Where子句具有多个值

时间:2015-05-31 15:18:31

标签: sql sql-server

我是SQL新手,我使用的是MS SQL Server Management Studio 2014.我有3个名为Pizza,Pizza_Topping和Topping的表。我想列出将TOPPING1和TOPPING2作为浇头的比萨饼。 这就是我想出来的,

select  Pizza.pizzaID, Pizza.pizzaName, Topping.toppingName

from Pizza left join Pizza_Topping on
Pizza.pizzaID = Pizza_Topping.pizzaID

left join Topping on
Topping.toppingID = Pizza_Topping.toppingID

where Topping.toppingName in ('topping1', 'topping2')

这给了我

pizzaID    pizzaName        toppingName
-------- ---------------- --------------
PZ002   |   PIZZA1       |    TOPPING1
PZ002   |   PIZZA1       |    TOPPING2
PZ010   |   PIZZA5       |    TOPPING1
PZ010   |   PIZZA5       |    TOPPING2
PZ011   |   PIZZA6       |    TOPPING1
PZ012   |   PIZZA7       |    TOPPING2

我只需要前四行,因为最后两个比萨只有一个浇头而不是两个。 我也试过这个,

GROUP BY Pizza.pizzaID,Pizza.pizzaName, Topping.toppingName HAVING COUNT(toppingName) >= 2 

但它没有给出预期的结果。如果我只显示pizzaIDpizzaName,我可以使用该行,但我也希望显示toppingName

更清楚,这正是我所期待的

pizzaID    pizzaName        toppingName
-------- ---------------- --------------
PZ002   |   PIZZA1       |    TOPPING1
PZ002   |   PIZZA1       |    TOPPING2
PZ010   |   PIZZA5       |    TOPPING1
PZ010   |   PIZZA5       |    TOPPING2

请告诉我如何实现这一结果。感谢

6 个答案:

答案 0 :(得分:0)

你几乎是对的。您需要从ToppingName

中删除GROUP BY
GROUP BY Pizza.pizzaID, Pizza.pizzaName
HAVING COUNT(toppingName) >= 2 

如果它也在SELECT,您还需要将其删除:

select p.pizzaID, p.pizzaName
from Pizza p join
     Pizza_Topping pt
     on p.pizzaID = pt.pizzaID join
     Topping t
     ont.toppingID = pt.toppingID
where t.toppingName in ('topping1', 'topping2')
group by p.pizzaID, p.pizzaName
having count(*) >= 2;

还要注意两件事。因为您对浇头有条件,所以left join是不必要的。您只是在寻找匹配项,因此inner join是合适的。表别名的使用使查询更容易编写和读取。

这假设比萨饼不能有重复的浇头。如果是,则将最后一个条件更改为:

having count(distinct t.toppingName) >= 2

答案 1 :(得分:0)

你必须两次加入pizza_topping和顶级表。

data

答案 2 :(得分:0)

我认为如果你可以在你的子查询中获得count()然后加入所有数量大于1的那个比萨饼,就可以更容易地做到这一点:

SELECT q1.pizzaID
    ,q1.PizzaName
    ,t.ToppingName
FROM (
    SELECT Pizza.pizzaID
        ,Pizza.pizzaName
        ,count(topping.ToppingName) total_count
    FROM Pizza
    INNER JOIN Pizza_Topping ON Pizza.pizzaID = Pizza_Topping.pizzaID
    INNER JOIN Topping ON Topping.toppingID = Pizza_Topping.toppingID
    GROUP BY Pizza.pizzaID
        ,Pizza.pizzaName
    HAVING count(topping.ToppingName) > 1
    ) q1
INNER JOIN Pizza_Topping pt ON q1.pizzaID = pt.pizzaID
INNER JOIN Topping t ON t.toppingID = pt.toppingID
WHERE t.toppingName in ('topping1', 'topping2')

答案 3 :(得分:0)

获取您的结果,而不是一流的名字。将其包装在视图中并使用Topping表进行内部连接。

答案 4 :(得分:0)

要包含浇头,您可以使用窗口化聚合函数执行COUNT逻辑:

SELECT p.pizzaID, p.pizzaName, dt.toppingName
FROM Pizza AS p 
JOIN
 (
   SELECT p.pizzaID, t.toppingName,
      COUNT(*) OVER (PARTITION BY p.pizzaID) AS cnt -- number of matching toppings
   FROM Pizza_Topping AS pt
   JOIN Topping AS t
     ON t.toppingID = pt.toppingID
   WHERE t.toppingName IN ('topping1', 'topping2')
 ) AS dt
  ON p.pizzaID = dt.pizzaID 
WHERE cnt = 2 -- number of searched toppings

答案 5 :(得分:0)

您可以通过使用仅限于Pizza Id的group by语句来解决此问题。请参考下面的查询。

   select  Pizza.pizzaID, Pizza.pizzaName, Pizza_Toppings.Remark
   from Pizza  join Pizza_Toppings on
   Pizza.pizzaID = Pizza_Toppings.pizzaID
   join Toppings on
   Toppings.toppingID = Pizza_Toppings.toppingID
   where Pizza.PizzaId in (
   select Pizza.PizzaID
   from Pizza  join Pizza_Toppings on
   Pizza.pizzaID = Pizza_Toppings.pizzaID
   join Toppings on
   Toppings.toppingID = Pizza_Toppings.toppingID
   where Toppings.TopingName in ('topping1', 'topping2')
   group by pizza.PizzaId 
   having count(Pizza.PizzaId ) > 1)

如果这不适用于您,请告诉我。