SQL Server两表查询结果不符问题求助(附SQL语句)
我来帮你一步步排查这两个求和结果不一致的问题,先把你的问题和SQL整理清楚:
执行UPDATE语句,将
rezervasyon表中每个operID对应的odeme_satis_kalan求和后更新到oper表的OdenecekTutar字段:UPDATE oper SET OdenecekTutar = ( SELECT CASE WHEN ROUND(SUM(rezervasyon.odeme_satis_kalan), 2) IS NOT NULL THEN ROUND(SUM(rezervasyon.odeme_satis_kalan), 2) ELSE 0 END FROM rezervasyon WHERE rezervasyon.oper = oper.operID )之后执行两个求和查询,预期结果应该一致,但实际不同:
SELECT ROUND(SUM(oper.OdenecekTutar),2) AS borc_from_oper FROM oper -- 结果:1372283,38SELECT ROUND(SUM(odeme_satis_kalan),2) AS borc_from_oper2 FROM rezervasyon -- 结果与上面不一致
下面是几个最可能导致差异的原因,你可以逐一验证:
1. 存在rezervasyon记录没有匹配的operID
你的UPDATE只处理了rezervasyon.oper能对应到oper.operID的记录,如果rezervasyon里有一些记录的oper值在oper表中找不到对应的operID,这些记录的odeme_satis_kalan会被计入第二个查询的总和,但不会被更新到任何oper的OdenecekTutar里,自然会产生差异。
验证查询:
SELECT SUM(odeme_satis_kalan) FROM rezervasyon WHERE oper NOT IN (SELECT operID FROM oper);
如果这个结果大于0,那就是这个原因导致的差异。
2. oper表中存在重复的operID
如果oper表中同一个operID有多条记录,UPDATE的时候每条记录都会被设置为对应rezervasyon的总和,相当于把同一个总和重复加了多次。比如operID=1有3条记录,对应rezervasyon的总和是100,那SUM(OdenecekTutar)会是300,但rezervasyon的总和还是100,结果肯定不一致。
验证查询:
SELECT operID, COUNT(*) FROM oper GROUP BY operID HAVING COUNT(*) > 1;
如果返回结果,说明存在重复的operID,这就是问题所在。
3. 四舍五入的顺序导致累积误差
你在UPDATE里先对每个oper的求和结果做了ROUND(...,2),然后再把这些四舍五入后的值求和;而第二个查询是先对所有odeme_satis_kalan求和再做ROUND(...,2)。这两种计算顺序的误差会被累积,导致最终结果不同。
举个简单例子:3条记录的odeme_satis_kalan都是0.004,单独四舍五入后都是0.00,总和是0.00;但先求和是0.012,四舍五入后是0.01,差异就出现了。
验证方法:去掉ROUND直接对比原始总和:
SELECT SUM(oper.OdenecekTutar) AS borc_from_oper_raw FROM oper; SELECT SUM(odeme_satis_kalan) AS borc_from_rezervasyon_raw FROM rezervasyon;
如果这两个原始值一致,那问题就出在四舍五入的顺序上。
4. UPDATE后有其他数据变更
有没有可能在你执行UPDATE之后,到运行那两个SELECT查询之间,有其他操作修改了oper.OdenecekTutar或者rezervasyon.odeme_satis_kalan的值?比如其他的UPDATE、插入或删除操作?
你可以重新执行一次UPDATE,然后立刻运行两个SELECT查询对比结果,看看是否一致。
5. UPDATE没有覆盖所有oper记录
虽然你的CASE语句已经把NULL转为0,但还是要确认oper表中有没有OdenecekTutar为NULL的记录——如果有,说明UPDATE没有正确覆盖这些记录,可能是执行时出错或者有隐藏的过滤条件。
验证查询:
SELECT COUNT(*) FROM oper WHERE OdenecekTutar IS NULL;
如果结果大于0,那你需要检查UPDATE语句是否有问题,或者有没有其他事务影响了执行结果。
内容的提问来源于stack exchange,提问作者Uğur Canbulat

