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

SQL月度统计需求:近3个月promo与deprecator求和差值转百分比

实现思路与SQL代码示例

先明确核心需求:按月份计算promo的总计数减去deprecator的总计数,再转换为占两者总和的百分比,同时只取最近3个月的数据。下面是分步思路和代码实现:

核心步骤拆解

  • 锁定近3个月数据:先过滤时间范围,确保只处理目标月份的数据。这里的"近3个月"默认指从当前月份往前推2个月的完整月份(比如当前是10月,取8、9、10月),用日期截断函数统一月份格式。
  • 按月份分组聚合:用条件聚合分别计算每个月promo和deprecator的总计数,避免多次子查询的冗余。
  • 计算百分比差值:通过(promo总和 - deprecator总和) / 两者总和 * 100得到百分比,同时用NULLIF处理总和为0的异常情况(避免除以0报错)。
  • 优化结果展示:可选保留小数位数,让结果更直观。

通用SQL代码示例(以PostgreSQL为例)

-- 按月份计算promo与deprecator的差值百分比,取近3个月数据
SELECT
    DATE_TRUNC('month', date_ref) AS month_ref, -- 截断到月份,作为分组依据
    -- 计算当月promo的总计数
    SUM(CASE WHEN evaluation_name = 'promo' THEN count_evaluation_name ELSE 0 END) AS total_promo,
    -- 计算当月deprecator的总计数
    SUM(CASE WHEN evaluation_name = 'deprecator' THEN count_evaluation_name ELSE 0 END) AS total_deprecator,
    -- 计算差值百分比,NULLIF避免除以0
    ROUND(
        (SUM(CASE WHEN evaluation_name = 'promo' THEN count_evaluation_name ELSE 0 END) - 
         SUM(CASE WHEN evaluation_name = 'deprecator' THEN count_evaluation_name ELSE 0 END)) 
        / NULLIF(SUM(count_evaluation_name) FILTER (WHERE evaluation_name IN ('promo', 'deprecator')), 0) 
        * 100,
        2 -- 保留2位小数
    ) AS difference_percentage
FROM
    your_table_name -- 替换成你的数据表名
WHERE
    -- 筛选近3个月的完整月份数据
    date_ref >= DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '2 months'
    -- 只处理目标类型,减少计算量
    AND evaluation_name IN ('promo', 'deprecator')
GROUP BY
    DATE_TRUNC('month', date_ref)
ORDER BY
    month_ref DESC; -- 按月份倒序,最近的月份在前

不同数据库的适配说明

如果使用其他数据库,需要调整日期处理函数:

  • MySQL:将DATE_TRUNC('month', date_ref)替换为DATE_FORMAT(date_ref, '%Y-%m-01'),CURRENT_DATE换成CURDATE(),INTERVAL '2 months'换成INTERVAL 2 MONTH。
  • SQL Server:将DATE_TRUNC('month', date_ref)替换为DATEFROMPARTS(YEAR(date_ref), MONTH(date_ref), 1),CURRENT_DATE - INTERVAL '2 months'换成DATEADD(MONTH, -2, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1))。
  • Oracle:将DATE_TRUNC('month', date_ref)替换为TRUNC(date_ref, 'MM'),CURRENT_DATE - INTERVAL '2 months'换成ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -2)。

关键细节提示

  • 用FILTER子句(PostgreSQL支持)或CASE限定只计算promo和deprecator的总和,避免其他evaluation_name的数据干扰结果。
  • NULLIF函数用来防止某个月份两类数据总计数为0时出现除以0的错误,此时百分比会返回NULL,你可以根据需求用COALESCE替换为0。
  • 如果"近3个月"指过去90天而非完整月份,可将WHERE条件改为date_ref >= CURRENT_DATE - INTERVAL '90 days',分组仍按月份处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 08:02:24