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

SQL关联MeterReading表查询当月及上月抄表读数实现方案

问题原因
  • 核心错误是子查询内的关联年月计算逻辑完全颠倒:你的思路是将子查询的「上月记录」计算出它对应的「当月年月」,再和主表的当月记录关联,但判断条件写反了:你判断的是当前月为1的场景,实际应该判断当前月为12的场景。当前逻辑会把2021年1月的记录标记为匹配2022年12月的主表记录,完全不符合业务逻辑,导致绝大多数记录关联不上。
  • 输出字段冗余,不需要返回TMR表的MeterID、YV2、MV2等中间计算字段,只需保留上月的读数类字段即可。
正确实现方案

方案1:通用自关联写法(兼容所有SQL版本)

不需要额外写子查询做年月转换,直接在关联条件里分场景匹配上月即可,逻辑清晰不易出错:

SELECT
    MR.MeterID,
    MR.YearVal,
    MR.MonthVal,
    MR.ReadingVal,
    MR.UsingVal,
    TMR.ReadingVal AS PrevVal,
    TMR.UsingVal AS PrevUsingVal,
    0 AS DelFlag
FROM MeterReading MR
LEFT JOIN MeterReading TMR
    ON MR.MeterID = TMR.MeterID
    AND (
        -- 非1月的情况:关联同年上月
        (MR.MonthVal > 1 AND TMR.YearVal = MR.YearVal AND TMR.MonthVal = MR.MonthVal - 1)
        OR
        -- 1月的情况:关联上年12月
        (MR.MonthVal = 1 AND TMR.YearVal = MR.YearVal - 1 AND TMR.MonthVal = 12)
    )
ORDER BY MR.YearVal, MR.MonthVal

方案2:窗口函数写法(兼容MySQL8.0+、PostgreSQL、SQL Server等支持窗口函数的数据库)

用LAG偏移函数直接取同个电表按年月排序的上一条记录值,自动处理跨年逻辑,代码更简洁、性能更优:

SELECT
    MeterID,
    YearVal,
    MonthVal,
    ReadingVal,
    UsingVal,
    LAG(ReadingVal) OVER (PARTITION BY MeterID ORDER BY YearVal, MonthVal) AS PrevVal,
    LAG(UsingVal) OVER (PARTITION BY MeterID ORDER BY YearVal, MonthVal) AS PrevUsingVal,
    0 AS DelFlag
FROM MeterReading
ORDER BY YearVal, MonthVal

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 12:06:02