You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MS Access SQL如何按餐厅分组查询各门店订单量前5的餐品

问题原因分析

  1. 第一版代码的问题:子查询直接取了全局的前5个餐品,没有按餐厅维度做区分,所以所有餐厅返回的都是相同的5款餐品。
  2. 第二版修改后代码的问题:子查询的过滤条件写了p2.ItemName = Products.ItemName,相当于每个餐品只和自身对比,必然满足TOP 5要求,所以会返回全量餐品;同时子查询仍然没有关联餐厅维度,没有实现「按餐厅单独算排名」的逻辑。另外你写的SUM(Quantity)*COUNT(Orders.OrderNumber)计算逻辑错误,销量总数直接用SUM(OrderDetails.Quantity)就可以统计所有订单里该餐品的售卖总份数。

正确实现思路

MS Access 不支持ROW_NUMBER()这类窗口函数,所以要通过关联子查询的方式,对每个餐厅下的每个餐品,统计有多少个同餐厅的餐品销量比它高,当这个数量小于5时,就是该餐厅的前5名餐品。


可运行的SQL代码

SELECT 
  t1.RestaurantName, 
  t1.ItemName, 
  t1.NumberofOrders
FROM (
  -- 先计算每个餐厅每个餐品的总销量
  SELECT 
    Restaurants.RestaurantName, 
    Products.ItemName, 
    SUM(OrderDetails.Quantity) AS NumberofOrders
    -- 如果需要统计下单次数而非售卖份数,可以替换成下方写法(MS Access不支持COUNT DISTINCT,所以用子查询实现)
    -- (SELECT COUNT(*) FROM Orders o WHERE o.RestID = Restaurants.RestID AND o.OrderNumber IN (SELECT OrderNumber FROM OrderDetails od WHERE od.ItemID=Products.ItemID)) AS NumberofOrders
  FROM Restaurants
  INNER JOIN Orders ON Restaurants.RestID = Orders.RestID
  INNER JOIN OrderDetails ON Orders.OrderNumber = OrderDetails.OrderNumber
  INNER JOIN Products ON OrderDetails.ItemID = Products.ItemID
  -- 如果你不需要用到FoodType的字段,这个JOIN可以直接删除
  INNER JOIN FoodType ON Products.ProdTypeID = FoodType.ProdType
  GROUP BY Restaurants.RestaurantName, Products.ItemName
) AS t1
WHERE (
  -- 统计同餐厅下,销量比当前餐品高的餐品数量,小于5即为前5名
  SELECT COUNT(*)
  FROM (
    SELECT 
      Restaurants.RestaurantName, 
      Products.ItemName, 
      SUM(OrderDetails.Quantity) AS SaleNum
    FROM Restaurants
    INNER JOIN Orders ON Restaurants.RestID = Orders.RestID
    INNER JOIN OrderDetails ON Orders.OrderNumber = OrderDetails.OrderNumber
    INNER JOIN Products ON OrderDetails.ItemID = Products.ItemID
    INNER JOIN FoodType ON Products.ProdTypeID = FoodType.ProdType
    GROUP BY Restaurants.RestaurantName, Products.ItemName
  ) AS t2
  WHERE t2.RestaurantName = t1.RestaurantName 
  AND t2.SaleNum > t1.NumberofOrders
) < 5
ORDER BY t1.RestaurantName, t1.NumberofOrders DESC;

特殊说明

如果存在同餐厅多个餐品销量并列第5的情况,查询会把所有并列的餐品都返回。如果需要严格只返回5个,可以把子查询里的<5改成<=4,或者调整子查询的排序逻辑,加上ItemName作为次要排序条件。


内容的提问来源于stack exchange,提问作者Beeeeee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 06:06:03