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

如何编写SQL查询获取按公司和产品分组的最近7张发票平均价格

问题分析与修正方案

你的原SQL逻辑存在核心错误,具体问题:

  • 子查询先取了全表最近7条记录,而非每个(Company, Product_Code)组内的最近7条,完全偏离需求
  • GROUP BY中包含price,会把同公司同产品但价格不同的行拆分成多个分组,无法得到正确的组内平均值
  • HAVING里的公司过滤可以提前放到WHERE中,提升查询效率

正确解法(使用窗口函数)

利用窗口函数ROW_NUMBER()给每个分组内的记录按发票日期倒序编号,筛选出每组前7条后再计算平均值,同时注意将字符串格式的发票日期转换为日期类型,避免排序错误:

MySQL 8.0+ 版本

SELECT 
    company, 
    product_code, 
    AVG(price) AS avg_recent_7_price
FROM (
    SELECT 
        *,
        -- 按公司+产品分组,每组内按发票日期倒序编号
        ROW_NUMBER() OVER (
            PARTITION BY company, product_code 
            ORDER BY STR_TO_DATE(invoice_date, '%d%m%Y') DESC
        ) AS row_num
    FROM your_table_name
    -- 提前过滤目标公司,减少计算量
    WHERE company IN ('A', 'B', 'C')
) AS ranked_records
-- 筛选每组最近7条记录
WHERE row_num <= 7
-- 仅按公司和产品分组计算平均值
GROUP BY company, product_code;

其他数据库适配说明

  • PostgreSQL:将日期转换函数改为TO_DATE(invoice_date, 'DDMMYYYY')
  • SQL Server:将日期转换函数改为CONVERT(date, invoice_date, 103)(假设发票日期格式为日/月/年)
    核心逻辑保持一致,仅日期转换函数随数据库方言调整。

逻辑拆解

  1. 子查询通过PARTITION BY company, product_code将数据拆分为独立的公司-产品分组
  2. ORDER BY STR_TO_DATE(...) DESC确保每个分组内最新的发票排在最前面,编号为1
  3. 外层筛选row_num <=7,保留每个分组的最近7条记录
  4. 最后按公司和产品分组,计算这7条记录的价格平均值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:43:22