MySQL窗口函数LAG疑问:ROWS子句未按预期检查前2行
问题分析与解决方案
原查询的核心问题
你使用LAG(pat_status)的方式存在逻辑偏差:LAG()是偏移量函数,它的作用是返回窗口内指定偏移量的单行数据(默认偏移1行,即前1行)。你设置的ROWS BETWEEN 2 PRECEDING AND CURRENT ROW只是限定了LAG()能访问的行范围,但不会让它遍历整个窗口检查条件——它依然只会取前1行的pat_status值进行判断。
这就解释了最后一行(visit_no=7066961)的结果:它的前1行pat_status是AIM(不含IC),所以CASE返回NULL,但你的需求是检查前2行内是否存在符合条件的记录,原写法无法覆盖这个逻辑。
正确的查询写法
要实现“检查当前行的前2行(含当前行)中是否存在pat_status包含IC的记录”,需要用聚合函数结合窗口子句,遍历整个窗口内的行进行判断。以下是两种可行的写法:
写法1:使用MAX函数
SELECT visit_no, mr_no, admit_date, dischg_date, pat_status, CASE WHEN MAX(CASE WHEN pat_status LIKE '%IC%' THEN 1 END) OVER(PARTITION BY mr_no ORDER BY admit_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) = 1 THEN 'Y' ELSE NULL END AS pat_status_check FROM chmadmtr WHERE mr_no = '508249';
写法2:使用COUNT函数
SELECT visit_no, mr_no, admit_date, dischg_date, pat_status, CASE WHEN COUNT(CASE WHEN pat_status LIKE '%IC%' THEN 1 END) OVER(PARTITION BY mr_no ORDER BY admit_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) > 0 THEN 'Y' ELSE NULL END AS pat_status_check FROM chmadmtr WHERE mr_no = '508249';
逻辑说明
- 聚合函数
MAX/COUNT会遍历窗口内的所有行(当前行 + 前2行),对每一行判断pat_status是否包含IC。 - 只要窗口内存在至少一条符合条件的记录,
MAX会返回1,COUNT会返回大于0的数值,此时CASE就会返回Y,完全符合你的需求。 - 针对最后一行,它的窗口包含:自身(
AIY)、前1行(AIM)、前2行(AIC)——因为前2行符合条件,所以pat_status_check会返回Y。
内容的提问来源于stack exchange,提问作者oscarmnz8
相关产品推荐
相关产品推荐

