SQL查询中的表
喜欢(cname,披萨)
客户(cname,area)
餐馆(rname,area)
出售(rname,披萨,价格)
参考:sqlfiddle.com/#!9/5be81e/1(包含代码和数据库架构)
预期结果:符合以下条件的餐馆列表
条件:
至少有2位顾客喜欢餐厅至少卖过一个披萨。 (他们不一定喜欢餐厅出售的同一个披萨,顾客和餐馆不一定要在同一地区)
餐厅必须至少出售3个披萨
餐厅出售的至少一个比萨饼必须比20美元便宜
我的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中最困难的部分。
更新:所有答案都很棒。结果是客户和餐厅不必在同一区域
答案 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
然而,这可能效率不高。为了获得更好的性能,我会为条件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
这是第三种方法,与第二种方法完全相同,但使用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
即可。而且您也不需要触摸表restaurants
和customers
。因此查询会变短:
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