无CTE/临时表场景下用NOT IN实现患者ID筛选的SQL逻辑校验
原有SQL逻辑偏差校验
原语句存在三处核心逻辑错误,同时存在运行性能隐患:
- 流程匹配维度写错:需求要排除的是refill流程下取得成功的患者,但子查询中筛选的是
ptprocess = 'embossing'的记录,过滤逻辑完全偏离业务规则。 - 外层筛选逻辑错位:原语句在外层加了
pTDescription <> 'Success'的条件,会错误纳入「既有失败refill记录、也有成功refill记录」的患者,不符合“从未成功完成refill”的判定标准。 - NOT IN的运行风险:子查询结果集过大时,NOT IN的逐值比对机制会造成长时间无响应;如果后续表中出现未被过滤的NULL值patientID,NOT IN会直接返回空结果集。
修正后的符合要求的SQL(无CTE、无临时表,仅使用NOT IN语法)
SELECT DISTINCT patientID AS PatientID FROM [dbo].[HPrecords] WHERE ptprocess = 'refill' AND patientID IS NOT NULL AND patiententrytime > '2021-04-06' AND patientID NOT IN ( SELECT DISTINCT patientID FROM [dbo].[HPrecords] WHERE ptprocess = 'refill' AND ptDescription = 'Success' AND patientID IS NOT NULL AND patiententrytime > '2021-04-06' )
运行优化说明
- 去掉外层不必要的状态判断:只要患者在指定时间范围内存在refill相关记录,且从未有过refill成功记录,就属于目标群体,不需要额外筛选外层记录的状态。
- 可通过建立
patientID, ptprocess, ptDescription, patiententrytime的联合索引,缩小子查询的数据扫描范围,解决长时间无法返回结果的问题。 - 如果需要把“从未发起过任何refill申请的患者”也纳入统计范围,可移除外层的
ptprocess = 'refill'筛选条件,直接从全表非空患者ID中排除有refill成功记录的群体。
内容的提问来源于stack exchange,提问作者learning programming
相关产品推荐
相关产品推荐

