SQL需求:为患者就诊记录匹配90天内最早既往就诊信息
高效实现患者就诊90天内最早既往就诊标记方案
首先修正原临时表创建语句的语法错误(DateVisit字段后缺失逗号):
CREATE TABLE #MyVisits ( PatientID char(10) NOT NULL, -- 字母数字格式患者ID VisitID char(10) NOT NULL, -- 字母数字格式就诊ID Clinic varchar(10) NOT NULL, -- 就诊诊所名称 DateVisit date NOT NULL, -- 就诊日期 EarliestVisitComment varchar(100) NULL -- 备注字段 );
前置优化:创建高效索引
为了大幅提升查询效率,先创建覆盖索引,让数据库能快速定位同患者的时间范围记录:
CREATE NONCLUSTERED INDEX IX_MyVisits_PatientID_DateVisit ON #MyVisits (PatientID, DateVisit) INCLUDE (Clinic, VisitID);
方案一:使用CROSS APPLY(SQL Server 适用)
通过CROSS APPLY为每条就诊记录关联符合条件的最早既往就诊,直接更新字段:
UPDATE mv SET EarliestVisitComment = CONCAT(prev.Clinic, ' ', prev.VisitID) FROM #MyVisits mv CROSS APPLY ( -- 筛选同患者、当前就诊前90天内的更早就诊,取最早的一条 SELECT TOP 1 Clinic, VisitID FROM #MyVisits prev_mv WHERE prev_mv.PatientID = mv.PatientID AND prev_mv.DateVisit >= DATEADD(DAY, -90, mv.DateVisit) AND prev_mv.DateVisit < mv.DateVisit ORDER BY prev_mv.DateVisit ASC ) prev;
- 若当前就诊无符合条件的既往记录,
CROSS APPLY返回空结果,EarliestVisitComment保持NULL,符合需求。
方案二:使用窗口函数 + CTE
通过FIRST_VALUE窗口函数在分区内直接计算符合条件的最早就诊信息:
WITH VisitCTE AS ( SELECT PatientID, VisitID, DateVisit, EarliestVisitComment, -- 在同患者分区内,取当前就诊前90天内的最早就诊拼接值 FIRST_VALUE(CONCAT(Clinic, ' ', VisitID)) OVER ( PARTITION BY PatientID ORDER BY DateVisit ASC RANGE BETWEEN INTERVAL 90 DAY PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW ) AS EarliestPrevVisit FROM #MyVisits ) UPDATE VisitCTE SET EarliestVisitComment = EarliestPrevVisit;
RANGE BETWEEN限定了时间范围,EXCLUDE CURRENT ROW排除当前就诊本身,确保只取既往记录。无符合条件记录时,函数返回NULL。
以上两种方案均基于集合运算,避免了逐行遍历(如游标)的低效操作,配合索引可高效处理大规模数据。
内容的提问来源于stack exchange,提问作者Telescope2334
相关产品推荐
相关产品推荐

