Temp表8月数据复制到9月对应行的SQL语句调试求助
排查并修正你的SQL更新语句
我来帮你排查下这个问题——你的SQL执行成功但没产生数据变更,主要是关联逻辑和筛选条件存在几个关键问题,咱们一步步拆解:
原SQL的核心问题
表别名的关联逻辑搞反了
你要更新的是9月的行(cy),需要取的是8月对应Pipeline的源数据(ny),但原语句里的关联条件是dateadd(day, 31, cy.Date) = ny.Date,这相当于找9月日期加31天的后续数据,完全和需求相反。正确的逻辑应该是:9月的日期 = 8月日期加31天,或者8月日期 = 9月日期减31天。Left Join + Where条件的过滤矛盾
原语句用了left join,但后续where year(ny.Date) = 2017会把所有没有匹配到ny数据的行过滤掉(因为ny.Date会是null,year(null)不满足等于2017)。而我们实际需要的是只更新存在对应8月数据的9月行,用inner join更合适,也更高效。日期筛选不够精准
原语句只限制了year(ny.Date)=2017,但没有明确锁定9月的目标行和8月的源行,可能会误匹配到其他年份的8/9月数据,或者非目标月份的数据。
修正后的SQL语句
UPDATE cy SET cy.[CY Actual Volume] = ny.[CY Actual Volume] FROM [dbo].[Temp] cy INNER JOIN [dbo].[Temp] ny ON cy.[Pipeline] = ny.[Pipeline] AND cy.Date = DATEADD(day, 31, ny.Date) WHERE -- 明确筛选要更新的是2017年9月、字段值为0的行 YEAR(cy.Date) = 2017 AND MONTH(cy.Date) = 9 AND cy.[CY Actual Volume] = 0 -- 明确源数据是2017年8月的行 AND YEAR(ny.Date) = 2017 AND MONTH(ny.Date) = 8
额外说明
- 用
INNER JOIN确保只有找到对应8月数据的9月行才会被更新,避免无效的匹配尝试。 - 精准锁定年份和月份,避免误操作其他时间段的数据(比如2018年的8/9月)。
- 关联条件
cy.Date = DATEADD(day, 31, ny.Date)正好匹配你的需求:8月1日加31天就是9月1日,完美对应同Pipeline的数据复制。
如果你担心DATEADD(day,31, ny.Date)会不会因为月份天数问题出错(比如8月有31天,加31天正好是9月1日,这个场景下是没问题的),也可以用更严谨的日期匹配方式,比如:
ON cy.[Pipeline] = ny.[Pipeline] AND YEAR(cy.Date) = YEAR(ny.Date) AND MONTH(cy.Date) = MONTH(ny.Date) + 1 AND DAY(cy.Date) = DAY(ny.Date)
这种方式可以适配所有同日期跨月份的场景,比如1月1日复制到2月1日(不管当月天数)。
内容的提问来源于stack exchange,提问作者user5098957
相关产品推荐
相关产品推荐

