如何修改现有SQL查询 同时返回当前及上一薪资周期数据
实现思路
直接在单查询内完成逻辑即可,核心是先复用你现有的薪资周期计算规则,再扩展过滤范围覆盖上一周期,不需要执行二次查询。
你原有代码重复写了3次薪资周期起止的计算逻辑,既不利于维护,也容易因为多处修改不一致导致结果错误,首先把这部分逻辑抽离为公共计算段,再基于当前周期的边界推导上一周期的时间范围:
- 上一薪资周期的结束时间 = 当前薪资周期的开始时间
- 上一薪资周期的开始时间 = 当前薪资周期开始时间往前推1个月(完全匹配你现有半月一周期的规则,不需要额外调整日期判断逻辑)
修改后可直接运行的代码
WITH pay_period AS ( SELECT -- 完全沿用你原有的当前周期计算规则,未做任何逻辑改动 CASE WHEN DAYOFMONTH(CURRENT_DATE) <= 15 THEN ADD_MONTHS(NEXT_DAY(LAST_DAY(CURRENT_DATE)), -1) ELSE ADD_DAYS( TO_DATE(LAST_DAY(CURRENT_DATE), 'YYYY-MM-DD'), CASE WHEN MONTH(CURRENT_DATE) IN (4,6,9,11) THEN -14 WHEN MONTH(CURRENT_DATE) IN (1,3,5,7,8,10,12) THEN -15 ELSE -12 END ) END AS curr_begin, CASE WHEN DAYOFMONTH(CURRENT_DATE) <= 15 THEN ADD_DAYS( TO_DATE(LAST_DAY(CURRENT_DATE), 'YYYY-MM-DD'), CASE WHEN MONTH(CURRENT_DATE) IN (4,6,9,11) THEN -14 WHEN MONTH(CURRENT_DATE) IN (1,3,5,7,8,10,12) THEN -15 ELSE -12 END ) ELSE LAST_DAY(CURRENT_DATE) END AS curr_end ) SELECT t."WORK_CENTER", t."WORK_DATE", t."AFE", t."PAYCODE", t."PERSONNEL_NUMBER", t."REPORTED_HOURS", t."REPORTED_MINS", t."POSITION_NUMBER", t."MILES", -- 可选:新增周期标记字段,快速区分数据归属周期,不需要可以删掉 CASE WHEN t."WORK_DATE" >= pp.curr_begin THEN '当前薪资周期' ELSE '上一薪资周期' END AS "period_tag", -- 保留原有返回的当前周期起止字段,不需要可以删掉 pp.curr_begin AS "begin_dt", pp.curr_end AS "end_dt" FROM Table__1 t CROSS JOIN pay_period pp WHERE t."WORK_CENTER" = @Prompt('enter prompt', 'A',,,) -- 过滤范围覆盖两个完整周期 AND t."WORK_DATE" >= ADD_MONTHS(pp.curr_begin, -1) AND t."WORK_DATE" < pp.curr_end ORDER BY t."WORK_DATE"
说明
- 原查询重复选取了两次
PERSONNEL_NUMBER字段,修改后的代码移除了这个冗余项,如果有特殊需要保留可以自行加回。 - 抽离CTE后,所有周期计算逻辑只维护一处,后续如果要调整薪资周期的日期规则,只需要修改CTE内的判断即可,不会出现过滤条件和返回字段的周期值不一致的问题。
- 这里的
CROSS JOIN是和单行的周期计算结果做关联,不会产生数据膨胀,性能和你原查询基本一致,远优于执行两次查询再合并结果的方案。 - 如果需要返回上一周期的起止字段,可以直接在CTE内新增
ADD_MONTHS(curr_begin, -1) AS prev_begin、curr_begin AS prev_end两个计算字段,直接在SELECT段取用即可。
内容的提问来源于stack exchange,提问作者ohsapman96
相关产品推荐
相关产品推荐

