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

MySQL按业务规则计算月度滞纳金 筛选符合条件的StatementItem条目

问题背景

现有StatementItem表存储企业账单明细:

  • 滞纳金、已享受服务费用对应si_amount为负值,其中sid=29的条目为滞纳金记录
  • 已缴纳服务款项对应si_amount为正值
    需要按规则计算指定月份客户滞纳金,通用公式为:
    late_fee = (出账满1个月且未被计收满3次滞纳金的服务总费用 + 累计已缴总金额) * 1.5%
    核心规则约束:
  • 服务项生成时间早于3条同客户滞纳金记录的,视为已累计计收3次滞纳金,不得计入当月计算基数
  • 仅出账时间早于当期账期截止日(如示例为2022-05-20)的服务项可纳入计算
实现方案

原查询存在三个问题:表别名引用错误、未过滤滞纳金条目本身、未实现「计收次数不足3次」的判断逻辑,修正后完整SQL如下:

SELECT 
    c.c_id,
    -- 符合条件的服务总费用
    COALESCE(
        (
            SELECT SUM(si.si_amount)
            FROM StatementItem si
            WHERE si.c_id = c.c_id 
                AND si.si_amount < 0 
                AND si.sid != 29 -- 排除滞纳金自身的负金额记录
                AND si.si_posting_date < '2022-05-20' -- 替换为对应计算月份的账期截止日
                -- 统计该服务项之后生成的滞纳金记录数,不足3条才符合条件
                AND (
                    SELECT COUNT(1)
                    FROM StatementItem late_count
                    WHERE late_count.c_id = si.c_id
                        AND late_count.sid = 29
                        AND late_count.si_posting_date > si.si_posting_date
                ) < 3
        ), 0
    ) AS total_eligible_for_late_fees,
    -- 累计已缴总金额
    COALESCE(
        (
            SELECT SUM(si_amount)
            FROM StatementItem si
            WHERE si.c_id = c.c_id 
                AND si.si_amount > 0
        ), 0
    ) AS all_payments_to_date,
    -- 计算最终滞纳金
    (total_eligible_for_late_fees + all_payments_to_date) * 0.015 AS late_fee
FROM Customer c;
优化说明
  • 用COALESCE处理SUM返回的NULL值,避免无符合条件记录时计算结果为空
  • 若表数据量较大,建议给StatementItem表添加(c_id, sid, si_posting_date)的联合索引,大幅提升子查询计数、求和的执行效率
  • 可将硬编码的账期日期'2022-05-20'替换为变量,适配不同月份的滞纳金计算需求

内容的提问来源于stack exchange,提问作者J.spenc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:45:31