按国家分组求不同列总和最大值,查询各国最受欢迎产品
解决每个国家最受欢迎产品的SQL问题
原SQL语句的问题
你的SQL存在几个语法和逻辑错误:
MAX()函数无法直接接收多个列作为参数,若要取多列最大值,多数SQL方言支持GREATEST()函数,但你在同一SELECT子句中使用了后续定义的别名(Ft、Vg、Mt)作为参数,这是不允许的——别名的解析顺序在聚合计算之后,无法被同一子句的函数引用。GROUP BY后的括号是多余的,直接指定列名即可。SELECT列表最后一列末尾的逗号会引发语法错误,必须删除。
解决方案
下面提供两种可行的实现方式,根据你的SQL方言选择:
方法一:使用CASE表达式(通用兼容)
这种方式直接计算各产品总和,通过CASE判断哪个产品的总和最大:
SELECT "Country", SUM("Fruit") AS Total_Fruit, SUM("Veg") AS Total_Veg, SUM("Meat") AS Total_Meat, CASE WHEN SUM("Fruit") >= SUM("Veg") AND SUM("Fruit") >= SUM("Meat") THEN 'Fruit' WHEN SUM("Veg") >= SUM("Fruit") AND SUM("Veg") >= SUM("Meat") THEN 'Veg' ELSE 'Meat' END AS Most_Popular_Product FROM "My_Data_Set" GROUP BY "Country";
方法二:使用窗口函数(适用于PostgreSQL、MySQL 8+、SQL Server等)
先将宽表转为长表,计算每个国家各产品的总和,再通过窗口函数排名,取排名第一的产品:
WITH CountryProductTotals AS ( SELECT "Country", 'Fruit' AS Product, SUM("Fruit") AS Total FROM "My_Data_Set" GROUP BY "Country" UNION ALL SELECT "Country", 'Veg' AS Product, SUM("Veg") AS Total FROM "My_Data_Set" GROUP BY "Country" UNION ALL SELECT "Country", 'Meat' AS Product, SUM("Meat") AS Total FROM "My_Data_Set" GROUP BY "Country" ), RankedProducts AS ( SELECT "Country", Product, Total, RANK() OVER (PARTITION BY "Country" ORDER BY Total DESC) AS ProductRank FROM CountryProductTotals ) SELECT "Country", Product AS Most_Popular_Product, Total AS Total_Sales FROM RankedProducts WHERE ProductRank = 1;
内容的提问来源于stack exchange,提问作者Bala Shanmugam
相关产品推荐
相关产品推荐

