使用SELECT DISTINCT仍出重复数据?SQL Server迁移后异常排查
DISTINCT在SQL Server 2016未生效的排查方案
核心原因分析
DISTINCT是基于所有选定字段的组合值进行去重,若返回重复行,本质是这些字段的组合在新服务器上被判定为不同值,而旧服务器(2014)判定为相同。结合版本迁移场景,常见诱因如下:
字段值的隐性差异:
- 若
AAV_GUID是字符串类型,新旧服务器的数据库排序规则可能不同(比如旧库是不区分大小写的CI排序,新库是区分大小写的CS排序),导致GUID中字母的大小写差异被视为不同值。 - 若
WI_PrdWellCnt是浮点类型(如float),表面显示的数值相同,但实际存储的精度存在细微差异,2014版本可能在比较时自动截断,2016版本保留了完整精度。
- 若
视图定义变更:
迁移过程中,视图V_ResultsProdBdgtOpsUpLiveBaseV4.5的定义可能被修改,比如旧视图对AAV_GUID做了UPPER()或LOWER()统一大小写处理,新视图未保留该逻辑;或者对数值字段的转换规则不同。
排查与解决步骤
1. 验证字段的实际值差异
执行以下查询,通过二进制转换查看字段的真实存储值,排查表面相同但实际不同的情况:
SELECT [UWI_vn], [WI_PrdWellCnt], [AAV_GUID], [InResFlag], -- 查看GUID的二进制存储 CAST([AAV_GUID] AS VARBINARY(MAX)) AS GUID_Binary, -- 查看数值字段的二进制存储 CAST([WI_PrdWellCnt] AS VARBINARY(MAX)) AS Cnt_Binary FROM [AAV_WellStore].[dbo].[V_ResultsProdBdgtOpsUpLiveBaseV4.5] WHERE [InResFlag] =1 AND [WI_PrdWellCnt] > 0 AND [UWI_vn] = '102/16-25-069-05W6/0'
若GUID_Binary或Cnt_Binary存在差异,即可确认是隐性值不同导致的问题。
2. 检查数据库排序规则
对比新旧服务器的数据库排序规则,执行:
SELECT name, collation_name FROM sys.databases WHERE name = 'AAV_WellStore'
若新库排序规则为区分大小写(含CS标识),可修改排序规则,或在查询中统一GUID的大小写:
SELECT DISTINCT [UWI_vn], [WI_PrdWellCnt], UPPER([AAV_GUID]) AS AAV_GUID, [InResFlag] FROM [AAV_WellStore].[dbo].[V_ResultsProdBdgtOpsUpLiveBaseV4.5] WHERE [InResFlag] =1 AND [WI_PrdWellCnt] > 0 AND [UWI_vn] = '102/16-25-069-05W6/0'
3. 排查视图定义差异
查看当前视图的定义,对比旧服务器上的版本:
EXEC sp_helptext '[AAV_WellStore].[dbo].[V_ResultsProdBdgtOpsUpLiveBaseV4.5]'
若发现字段处理逻辑不一致(比如数值转换、字符串格式化),修正视图定义与旧服务器保持一致即可。
4. 处理浮点数值精度问题
若WI_PrdWellCnt是浮点类型,将其转换为精确数值类型后再去重:
SELECT DISTINCT [UWI_vn], CAST([WI_PrdWellCnt] AS DECIMAL(18,0)) AS WI_PrdWellCnt, [AAV_GUID], [InResFlag] FROM [AAV_WellStore].[dbo].[V_ResultsProdBdgtOpsUpLiveBaseV4.5] WHERE [InResFlag] =1 AND [WI_PrdWellCnt] > 0 AND [UWI_vn] = '102/16-25-069-05W6/0'
内容的提问来源于stack exchange,提问作者KickingAustin
相关产品推荐
相关产品推荐

