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

SQL新手求助:按国家分组查询销量最高的产品

获取每个国家最受欢迎的产品

你当前的查询是把每种产品的总销量作为单独列返回,要得到每个国家销量最高的产品,需要先把这些列转换成行(也就是“逆透视”),再找出每个国家销量最大的产品。

方法一:通用SQL写法(适用于所有数据库)

这个方法用UNION ALL把各产品的销量数据合并成统一的行结构,再用窗口函数筛选出每个国家的Top1产品:

WITH country_product_sales AS (
    -- 把原查询的列转成国家、产品、总销量的行格式
    SELECT Country, 'Liquids' AS Product, SUM(Liquids) AS TotalSales
    FROM marketing_data
    GROUP BY Country
    UNION ALL
    SELECT Country, 'Veg' AS Product, SUM(Veg) AS TotalSales
    FROM marketing_data
    GROUP BY Country
    UNION ALL
    SELECT Country, 'NonVeg' AS Product, SUM(NonVeg) AS TotalSales
    FROM marketing_data
    GROUP BY Country
    UNION ALL
    SELECT Country, 'Fish' AS Product, SUM(Fish) AS TotalSales
    FROM marketing_data
    GROUP BY Country
    UNION ALL
    SELECT Country, 'Chocolates' AS Product, SUM(Chocolates) AS TotalSales
    FROM marketing_data
    GROUP BY Country
    UNION ALL
    SELECT Country, 'Commodities' AS Product, SUM(Commodities) AS TotalSales
    FROM marketing_data
    GROUP BY Country
),
ranked_products AS (
    -- 对每个国家的产品按销量降序排名
    SELECT 
        Country,
        Product,
        TotalSales,
        -- 用ROW_NUMBER()会给并列销量的产品分配不同排名,只取第一个;用RANK()会保留并列的多个Top1
        ROW_NUMBER() OVER (PARTITION BY Country ORDER BY TotalSales DESC) AS rn
    FROM country_product_sales
)
-- 筛选出每个国家排名第一的产品
SELECT Country, Product AS "Most popular product"
FROM ranked_products
WHERE rn = 1;

关键说明:

  • UNION ALL:把每种产品的销量统计结果合并成一个数据集,每行对应一个国家的一种产品和它的总销量。
  • ROW_NUMBER() OVER (PARTITION BY Country ORDER BY TotalSales DESC):按国家分组,每组内按销量从高到低给产品排名,每个国家的销量最高产品会得到排名1。
  • 如果想保留同国家销量并列第一的多个产品,把ROW_NUMBER()换成RANK()即可。

方法二:用UNPIVOT简化(适用于SQL Server、Oracle等支持UNPIVOT的数据库)

如果你的数据库支持UNPIVOT语法,可以简化列转行的步骤:

WITH country_product_sales AS (
    -- 先按国家统计各产品总销量,再用UNPIVOT转成行
    SELECT Country, Product, TotalSales
    FROM (
        SELECT 
            Country,
            SUM(Liquids) AS TotalLiquids,
            SUM(Veg) AS TotalVeg,
            SUM(NonVeg) AS TotalNonVeg,
            SUM(Fish) AS TotalFish,
            SUM(Chocolates) AS TotalChocolates,
            SUM(Commodities) AS TotalCommodities
        FROM marketing_data
        GROUP BY Country
    ) AS src
    UNPIVOT (
        TotalSales FOR Product IN (
            TotalLiquids, TotalVeg, TotalNonVeg, TotalFish, TotalChocolates, TotalCommodities
        )
    ) AS unpvt
),
ranked_products AS (
    SELECT 
        Country,
        Product,
        REPLACE(Product, 'Total', '') AS "Most popular product", -- 去掉Product列的Total前缀
        ROW_NUMBER() OVER (PARTITION BY Country ORDER BY TotalSales DESC) AS rn
    FROM country_product_sales
)
SELECT Country, "Most popular product"
FROM ranked_products
WHERE rn = 1;

关键说明:

  • UNPIVOT直接把原查询的多列(TotalLiquids等)转换成Product和TotalSales两列,比UNION ALL更简洁。
  • REPLACE(Product, 'Total', '')是把TotalLiquids这类名称转换成你想要的Liquids格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:45:32