SQL Server 2019:如何在带CTE的查询中添加Case When实现条件返回单行
问题描述
我有一个需要返回单个值的查询,但当前查询返回两行。需求如下:当列[STJH_DATE_ACTION] <= GETDATE()时,仅显示第一行;当所有行的[STJH_DATE_ACTION] > GETDATE()时,显示第二行。我尝试了以下查询:
WITH CTE AS ( SELECT ROW_NUMBER () OVER (PARTITION BY ST_ID, STJ_JOUR ORDER BY A.STJH_DATE_ACTION DESC) AS RN, * FROM bloc.W_TMD_JOUR_HISTORIQUE A ) SELECT * FROM CTE WHERE CTE.ST_ID = 268 AND CTE.STJ_JOUR = 1
当前查询结果如图所示:
解决方案
你可以在WHERE子句中结合CASE WHEN逻辑,根据日期条件筛选对应行号的记录,实现如下:
WITH CTE AS ( SELECT ROW_NUMBER () OVER (PARTITION BY ST_ID, STJ_JOUR ORDER BY A.STJH_DATE_ACTION DESC) AS RN, * FROM bloc.W_TMD_JOUR_HISTORIQUE A ) SELECT * FROM CTE WHERE CTE.ST_ID = 268 AND CTE.STJ_JOUR = 1 AND RN = CASE -- 若分组内存在STJH_DATE_ACTION <= 当前日期的记录,取第一行 WHEN EXISTS (SELECT 1 FROM CTE c WHERE c.ST_ID = CTE.ST_ID AND c.STJ_JOUR = CTE.STJ_JOUR AND c.STJH_DATE_ACTION <= GETDATE()) THEN 1 -- 若所有记录的STJH_DATE_ACTION都大于当前日期,取第二行 ELSE 2 END
逻辑说明
- 利用
EXISTS检查当前分组(ST_ID+STJ_JOUR)下是否存在日期小于等于当前日期的记录:- 存在则筛选行号
RN=1的记录(按日期降序排列的首行) - 不存在则筛选行号
RN=2的记录
- 存在则筛选行号
如果更倾向于直接基于首行日期判断,也可以用以下简化写法:
WITH CTE AS ( SELECT ROW_NUMBER () OVER (PARTITION BY ST_ID, STJ_JOUR ORDER BY A.STJH_DATE_ACTION DESC) AS RN, * FROM bloc.W_TMD_JOUR_HISTORIQUE A ) SELECT * FROM CTE WHERE CTE.ST_ID = 268 AND CTE.STJ_JOUR = 1 AND RN = CASE WHEN (SELECT TOP 1 STJH_DATE_ACTION FROM CTE c WHERE c.ST_ID=CTE.ST_ID AND c.STJ_JOUR=CTE.STJ_JOUR ORDER BY c.STJH_DATE_ACTION DESC) <= GETDATE() THEN 1 ELSE 2 END
两种写法均可实现需求,可根据实际场景选择。
内容的提问来源于stack exchange,提问作者Moja
相关产品推荐
相关产品推荐

