SQL Server中如何在聚合SQL子查询内实现DateAdd计算
可行实现方案
你可以根据自己的代码场景选以下两种写法:
- 直接嵌套法:不需要调整你已经写好的子查询逻辑,直接把
DATEADD函数套在计算maxBoosterDatum的子查询外层即可,示例如下:
-- 以下示例为在最大接种日期基础上加180天,你可以按需替换DATEADD的间隔单位、间隔数值 DATEADD(day, 180, (SELECT MAX(maxBoosterDatum) FROM (VALUES (Quests.[Datum Booster Impfung]), (Quests.[Datum Booster Impfung nach 1]), (Quests.[Datum Booster Impfung nach 2])) AS DatumB(maxBoosterDatum)) ) AS calculatedBoosterDate, -- 替换为你需要的运算结果别名
注:你原有的子查询本身返回单个日期类型的标量值,完全满足DATEADD第三个日期入参的语法要求,直接嵌套不会有问题。
- CROSS APPLY预计算法:如果后续你需要多次引用这个最大加强针日期做其他运算(比如算多个时间节点的到期日),更推荐用
CROSS APPLY先把maxBoosterDatum的结果提前计算出来,后续直接引用别名即可,不用重复写嵌套子查询,代码可读性和维护性更高,示例如下:
SELECT -- 其他查询字段正常书写 maxB.maxBoosterDatum, -- 直接取原始的最大接种日期 DATEADD(month, 6, maxB.maxBoosterDatum) AS boosterHalfYearValidDate, DATEADD(month, 12, maxB.maxBoosterDatum) AS boosterOneYearValidDate, -- 其他需要的计算字段、查询字段 FROM Quests CROSS APPLY ( SELECT MAX(maxBoosterDatum) AS maxBoosterDatum FROM (VALUES (Quests.[Datum Booster Impfung]), (Quests.[Datum Booster Impfung nach 1]), (Quests.[Datum Booster Impfung nach 2]) ) AS DatumB(maxBoosterDatum) ) AS maxB -- 后续WHERE、JOIN等语句按原有逻辑正常写即可
补充说明:上述逻辑里的
MAX聚合会自动忽略三个日期列中的NULL值,只有当三列全为NULL时,maxBoosterDatum才会返回NULL,此时DATEADD也会同步返回NULL,不会触发语法报错。如果需要全NULL场景下返回指定默认日期,可以在DATEADD外层套一层ISNULL或者COALESCE做兜底处理。
内容的提问来源于stack exchange,提问作者Marco Mikuš
相关产品推荐
相关产品推荐

