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

多供应商付款同比百分比差异SQL查询问题求助

嘿,我来帮你搞定这个供应商付款同比百分比差异的问题!根据你描述的需求,我假设你用的是标准SQL(如果是MySQL、PostgreSQL这类特定数据库,我可以再调整细节),下面是具体的实现思路和可直接复用的代码:

供应商付款同比增长计算方案

首先,核心思路是用**窗口函数LAG()**来获取每个供应商上一年的付款金额——它能帮我们把“去年的付款额(old)”和“今年的付款额(new)”放在同一行,完美适配你((new-old)/old)*100的计算需求。

第一步:先匹配上一年的付款数据

假设你的表名为vendor_payments,字段包含company_name(供应商名称)、payment_year(付款年份)、total_payment(当年总付款额),先写基础查询来关联上一年的数据:

SELECT
    company_name,
    payment_year,
    total_payment,
    -- 按供应商分组、年份升序,取上一行的付款额(即去年的金额)
    LAG(total_payment) OVER (PARTITION BY company_name ORDER BY payment_year) AS previous_year_payment
FROM vendor_payments
ORDER BY company_name, payment_year;

第二步:计算同比百分比(处理异常情况)

接下来基于上面的子查询,套用公式计算同比,同时要处理两种容易报错的场景:

  • 供应商第一年的数据,没有上一年参考值,同比设为0%
  • 上一年付款额为0,避免除以0报错,同比也设为0%(你也可以根据需求改成NULL)

完整的最终查询代码:

SELECT
    company_name,
    payment_year,
    CONCAT('$', total_payment) AS formatted_payment, -- 格式化金额为带$的样式
    CASE
        -- 无上年数据或上年付款为0时返回0%
        WHEN previous_year_payment IS NULL OR previous_year_payment = 0 THEN '0%'
        -- 正常计算同比,保留整数(可调整ROUND的第二个参数控制小数位数)
        ELSE CONCAT(ROUND(((total_payment - previous_year_payment) / previous_year_payment) * 100, 0), '%')
    END AS yoy_growth
FROM (
    SELECT
        company_name,
        payment_year,
        total_payment,
        LAG(total_payment) OVER (PARTITION BY company_name ORDER BY payment_year) AS previous_year_payment
    FROM vendor_payments
) AS subquery
ORDER BY company_name, payment_year;

实际结果示例(和你期望的一致)

执行后会得到类似这样的输出:

company_namepayment_yearformatted_paymentyoy_growth
Company A2015$4000%
Company A2016$4000%
Company A2017$800100%
Company B2014$2000%

针对月度存储数据的调整

如果你是按月存储明细数据,但需要按年计算同比,只需要先按月数据聚合成年度总付款,再套上面的逻辑即可:

-- 先把月度数据聚合为年度总付款
WITH annual_payments AS (
    SELECT
        company_name,
        EXTRACT(YEAR FROM payment_month) AS payment_year, -- 假设payment_month是日期类型
        SUM(total_payment) AS total_payment
    FROM vendor_payments
    GROUP BY company_name, EXTRACT(YEAR FROM payment_month)
)
-- 再计算同比
SELECT
    company_name,
    payment_year,
    CONCAT('$', total_payment) AS formatted_payment,
    CASE
        WHEN previous_year_payment IS NULL OR previous_year_payment = 0 THEN '0%'
        ELSE CONCAT(ROUND(((total_payment - previous_year_payment) / previous_year_payment) * 100, 0), '%')
    END AS yoy_growth
FROM (
    SELECT
        company_name,
        payment_year,
        total_payment,
        LAG(total_payment) OVER (PARTITION BY company_name ORDER BY payment_year) AS previous_year_payment
    FROM annual_payments
) AS subquery
ORDER BY company_name, payment_year;

要是运行代码还有报错,你可以把具体错误信息告诉我,我再帮你针对性排查~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:01:57