在同一区域找到至少2个客户,他们至少喜欢在SQL中销售的一个披萨

时间:2018-02-25 06:50:08

标签: mysql sql

SQL查询中的表

  1. 喜欢(cname,披萨)

  2. 客户(cname,area)

  3. 餐馆(rname,area)

  4. 出售(rname,披萨,价格)

  5. 参考:sqlfiddle.com/#!9/5be81e/1(包含代码和数据库架构)

    预期结果:符合以下条件的餐馆列表

    条件

    1. 至少有2位顾客喜欢餐厅至少卖过一个披萨。 (他们不一定喜欢餐厅出售的同一个披萨,顾客和餐馆不一定要在同一地区)

    2. 餐厅必须至少出售3个披萨

    3. 餐厅出售的至少一个比萨饼必须比20美元便宜

    4. 我的SQL代码:

      SELECT r.rname
      FROM restaurants r
      WHERE EXISTS(SELECT 1
               FROM sells s 
               INNER JOIN likes l ON l.pizza = s.pizza
               GROUP BY c.area
               HAVING COUNT(l.pizza) >= 2
               WHERE s.rname = r.rname 
               AND s.pizza >=3 
               AND s.price <20
               )
      

      我在几个其他SQL帖子中加入了这个代码,这些帖子促进了WHERE EXIST的使用。现在我陷入了条件1中最困难的部分。

      更新:所有答案都很棒。结果是客户和餐厅不必在同一区域

1 个答案:

答案 0 :(得分:1)

没有任何子查询,但有一个巨大的连接:

SELECT r.rname
FROM restaurants r
JOIN sells s ON s.rname = r.rname
LEFT JOIN likes l on l.pizza = s.pizza
LEFT JOIN customers c
  ON  c.area  = r.area
  AND c.cname = l.cname
GROUP BY r.rname
HAVING 1
   AND COUNT(DISTINCT c.cname) >= 2 -- cond. 1
   AND COUNT(DISTINCT s.pizza) >= 3 -- cond. 2
   AND MIN(s.price) < 20            -- cond. 3
ORDER BY r.rname

Demo

然而,这可能效率不高。为了获得更好的性能,我会为条件1编写一个查询,为条件2和3编写一个查询。然后加入它们:

SELECT *
FROM (
    SELECT r.rname
    FROM restaurants r
    JOIN sells s ON s.rname = r.rname
    JOIN likes l on l.pizza = s.pizza
    JOIN customers c
      ON  c.area  = r.area
      AND c.cname = l.cname
    GROUP BY r.rname
    HAVING COUNT(DISTINCT c.cname) >= 2
) t1
NATURAL JOIN (
    SELECT s.rname
    FROM sells s
    GROUP BY s.rname
    HAVING MIN(s.price) < 20 
       AND COUNT(*) >= 3
) t2

Demo

这是第三种方法,与第二种方法完全相同,但使用EXISTS子查询而不是JOIN。

SELECT r.rname
FROM restaurants r
JOIN sells s ON s.rname = r.rname
JOIN likes l on l.pizza = s.pizza
JOIN customers c
  ON  c.area  = r.area
  AND c.cname = l.cname
GROUP BY r.rname
HAVING COUNT(DISTINCT c.cname) >= 2
   AND EXISTS (
     SELECT s.rname
     FROM sells s
     WHERE s.rname = r.rname
     HAVING MIN(s.price) < 20 
        AND COUNT(*) >= 3
)

如果喜欢披萨的顾客不需要与餐厅位于同一区域,您只需删除条件c.area = r.area即可。而且您也不需要触摸表restaurantscustomers。因此查询会变短:

SELECT s.rname
FROM sells s
LEFT JOIN likes l on l.pizza = s.pizza
GROUP BY s.rname
HAVING COUNT(DISTINCT l.cname) >= 2
   AND COUNT(DISTINCT s.pizza) >= 3
   AND MIN(s.price) < 20