SSMS中CASE语句条件失效:同条件在WHERE可用但CASE中丢失记录
解决SSMS统计时丢失记录的问题
核心问题排查与修复
先检查字段名是否笔误
你的第一个CASE语句里用的是json_error_field1,但后面三个CASE用的是json_error_field——字段名少了个1!这大概率是导致记录丢失的直接原因。字段名不匹配会让条件判断完全失效,符合field1='blue'的记录可能因为这个笔误,既不满足correct的条件,也不满足其他错误类型的条件,最终被所有统计列排除。处理
field1为NULL的情况
因为field1允许为NULL,而[field1] = 'blue'这类判断在field1为NULL时会返回UNKNOWN,直接走到CASE的ELSE分支(计为0)。如果不需要统计field1为NULL的无效记录,直接在WHERE子句里加上过滤条件:AND [field1] IS NOT NULL AND [field1] IN ('blue', 'red', 'green', 'yellow') -- 包含所有需要统计的field1值这样既能过滤掉无效的NULL值,又能保留所有你需要统计的4种错误场景对应的
field1类型。优化CASE条件,覆盖所有场景
确保每个field1类型的记录都能被分到某个统计列里,比如给每种field1类型增加“其他错误”的统计,避免因为未覆盖的错误值导致记录丢失:-- 以blue类型为例,增加其他错误统计 ,convert(float,sum(case when [field1] = 'blue' and json_value([json_error_field],'$.error1') is not null and json_value([json_error_field],'$.error1') not in ('late','wrong','missing') then 1 else 0 end))as 'error1_other'精准定位丢失的记录
找到那条丢失的记录,单独查询它的字段值,核对CASE条件:SELECT [field1], [timestampfield1], [json_error_field] FROM [DB]..[table] WHERE [datefield] between cast(@start_date as date) and cast(@end_date as date) -- 结合你知道的这条记录的特征,比如特定ID或日期看它到底不满足哪个条件,就能快速解决问题。
修正后的完整代码示例
SELECT -- blue类型统计 convert(float,sum(case when [field1] = 'blue' and json_value([json_error_field],'$.error1') is null then 1 else 0 end))as 'error1_correct' ,convert(float,sum(case when [field1] = 'blue' and json_value([json_error_field],'$.error1') = 'late' then 1 else 0 end))as 'error1_late' ,convert(float,sum(case when [field1] = 'blue' and json_value([json_error_field],'$.error1') = 'wrong' then 1 else 0 end))as 'error1_wrong' ,convert(float,sum(case when [field1] = 'blue' and json_value([json_error_field],'$.error1') = 'missing' then 1 else 0 end))as 'error1_missing' ,convert(float,sum(case when [field1] = 'blue' and json_value([json_error_field],'$.error1') is not null and json_value([json_error_field],'$.error1') not in ('late','wrong','missing') then 1 else 0 end))as 'error1_other' -- red类型统计(示例,对应第二种错误场景) ,convert(float,sum(case when [field1] = 'red' and json_value([json_error_field],'$.error2') is null then 1 else 0 end))as 'error2_correct' ,convert(float,sum(case when [field1] = 'red' and json_value([json_error_field],'$.error2') = 'late' then 1 else 0 end))as 'error2_late' FROM [DB]..[table] WHERE [datefield] between cast(@start_date as date) and cast(@end_date as date) AND [field1] IS NOT NULL AND [field1] IN ('blue', 'red', 'green', 'yellow')
内容的提问来源于stack exchange,提问作者anotherdataguy
相关产品推荐
相关产品推荐

