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

如何编写SQL查询找出每年销售额持续增长的产品名称?

问题:找出每年销售额持续增长的产品名称

表结构与数据

产品表(Product)

列:PRODUCT_ID(产品ID)、PRODUCT_NAME(产品名称)

PRODUCT_IDPRODUCT_NAME
100NOKIA
200IPHONE
300SAMSUNG
400OPPO

销售表(Sales)

列:SALE_ID(销售ID)、PRODUCT_ID(产品ID)、YEAR(年份)、QUANTITY(销量)、PRICE(单价)

SALE_IDPRODUCT_IDYEARQUANTITYPRICE
11002010255000
21002011165000
3100201285000
42002010109000
52002011159000
62002012209000
73002010207000
83002011187000
93002012207000
104002010157000
114002011187000
124002012227000
134002013237000

说明:Quantity为每年售出的产品数量,Price为产品销售单价。

需求

编写SQL查询,找出每年销售额持续增长的产品名称。

预期输出

PRODUCT_NAME
IPHONE
OPPO

现有查询问题

你提供的SQL仅能处理单个销售额增长产品的场景,无法正确返回多个符合条件的产品。问题出在最后一步:通过max_val = (SELECT MAX(max_val) FROM cte3)只选取了增长次数最多的产品,但我们需要的是所有没有出现销售额下降或持平的产品,和增长次数多少无关。

原查询的逻辑缺陷:

  1. LAG函数第三个参数设为当前销售额,导致首个年份的diff为0、val为0,这部分没问题;但后续通过SUM(val)统计增长次数,再取最大值的逻辑,会漏掉那些增长次数少但全程持续增长的产品(比如IPHONE有2次增长,OPPO有3次,原查询只会返回OPPO)。

正确解法

核心思路:对每个产品,检查其所有年份的销售额是否均严格大于前一年的销售额,即不存在任何一个年份的销售额≤前一年的情况。

实现SQL

WITH product_sales AS (
    SELECT 
        p.PRODUCT_NAME,
        s.PRODUCT_ID,
        s.YEAR,
        s.QUANTITY * s.PRICE AS total_sales,
        LAG(s.QUANTITY * s.PRICE) OVER (PARTITION BY s.PRODUCT_ID ORDER BY s.YEAR) AS prev_year_sales
    FROM Sales s
    JOIN Product p ON s.PRODUCT_ID = p.PRODUCT_ID
)
SELECT DISTINCT PRODUCT_NAME
FROM product_sales
WHERE PRODUCT_ID NOT IN (
    SELECT PRODUCT_ID
    FROM product_sales
    WHERE prev_year_sales IS NOT NULL AND total_sales <= prev_year_sales
);

逻辑说明

  1. product_sales CTE:计算每个产品每年的总销售额,并通过LAG获取前一年的销售额(首个年份的prev_year_sales为NULL)。
  2. 子查询:筛选出存在销售额下降或持平的产品ID。
  3. 主查询:排除上述产品ID,剩下的就是所有销售额持续增长的产品名称。

另一种更简洁的写法(使用COUNT和CASE判断):

WITH product_sales AS (
    SELECT 
        p.PRODUCT_NAME,
        s.PRODUCT_ID,
        s.QUANTITY * s.PRICE AS total_sales,
        LAG(s.QUANTITY * s.PRICE) OVER (PARTITION BY s.PRODUCT_ID ORDER BY s.YEAR) AS prev_year_sales
    FROM Sales s
    JOIN Product p ON s.PRODUCT_ID = p.PRODUCT_ID
)
SELECT PRODUCT_NAME
FROM product_sales
GROUP BY PRODUCT_ID, PRODUCT_NAME
HAVING COUNT(CASE WHEN prev_year_sales IS NOT NULL AND total_sales <= prev_year_sales THEN 1 END) = 0;

这种写法通过分组后统计“销售额未增长”的次数,次数为0的产品即为符合条件的产品。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 19:20:03