Snowflake基于最大值创建列:餐厅销售数据需求实现
解决门店每日销量最高菜品的SQL实现问题
原SQL的问题分析
你的SQL存在几个关键错误:
- CASE语法错误:
case when max(Units_sold_Saturday) then Menu_item不符合语法规则,CASE WHEN后必须是布尔判断条件(比如判断当前行销量是否等于组内最大值),不能直接放聚合函数。 - 聚合与非聚合字段混用:使用
max()聚合函数但未通过GROUP BY指定分组字段,数据库无法确定如何计算每个门店的最大值。 - 别名格式问题:部分数据库(如MySQL)会将单引号包裹的
'SaturdayItem'识别为字符串而非列别名,应改用反引号或直接省略引号(名称无特殊字符时)。
正确实现方案
要获取每个门店周六、周日销量最高的菜品,并输出每个门店一行的结果,推荐使用窗口函数+条件聚合的方式,无需提前创建空表。
方案1:仅取单个销量最高菜品(若并列取第一个)
适用于不需要保留并列最高菜品的场景,用ROW_NUMBER()给每个门店的菜品按销量排序:
SELECT store_id, MAX(CASE WHEN s_rank = 1 THEN Menu_Item END) AS SaturdayItem, MAX(CASE WHEN su_rank = 1 THEN Menu_Item END) AS SundayItem FROM ( SELECT store_id, Menu_Item, -- 按门店分组,周六销量降序排名 ROW_NUMBER() OVER (PARTITION BY store_id ORDER BY Units_sold_Saturday DESC) AS s_rank, -- 按门店分组,周日销量降序排名 ROW_NUMBER() OVER (PARTITION BY store_id ORDER BY Units_sold_Sunday DESC) AS su_rank FROM your_table_name -- 替换为你的表名 ) ranked_data GROUP BY store_id;
方案2:保留所有并列最高菜品
如果有多个菜品销量并列第一,需要全部展示,可将ROW_NUMBER()替换为RANK(),并使用字符串拼接函数(不同数据库函数不同):
- MySQL 使用
GROUP_CONCAT:
SELECT store_id, GROUP_CONCAT(DISTINCT CASE WHEN s_rank = 1 THEN Menu_Item END SEPARATOR ', ') AS SaturdayItem, GROUP_CONCAT(DISTINCT CASE WHEN su_rank = 1 THEN Menu_Item END SEPARATOR ', ') AS SundayItem FROM ( SELECT store_id, Menu_Item, RANK() OVER (PARTITION BY store_id ORDER BY Units_sold_Saturday DESC) AS s_rank, RANK() OVER (PARTITION BY store_id ORDER BY Units_sold_Sunday DESC) AS su_rank FROM your_table_name ) ranked_data GROUP BY store_id;
- PostgreSQL/SQL Server 使用
STRING_AGG:
SELECT store_id, STRING_AGG(DISTINCT CASE WHEN s_rank = 1 THEN Menu_Item END, ', ') AS SaturdayItem, STRING_AGG(DISTINCT CASE WHEN su_rank = 1 THEN Menu_Item END, ', ') AS SundayItem FROM ( SELECT store_id, Menu_Item, RANK() OVER (PARTITION BY store_id ORDER BY Units_sold_Saturday DESC) AS s_rank, RANK() OVER (PARTITION BY store_id ORDER BY Units_sold_Sunday DESC) AS su_rank FROM your_table_name ) ranked_data GROUP BY store_id;
逻辑说明
- 子查询中通过窗口函数
ROW_NUMBER()/RANK(),按门店分组,对周六、周日的销量分别降序排名,标记出每个门店销量最高的菜品(排名为1)。 - 外层通过
GROUP BY store_id聚合每个门店的数据,用MAX()或字符串拼接函数提取排名第一的菜品,最终得到每个门店一行的结果。
内容的提问来源于stack exchange,提问作者milo204
相关产品推荐
相关产品推荐

