在 Oracle 中查找下一个和上一个工作日
我的查询有点像这样:
select 1 from dual where :p1_task_date in (sysdate,sysdate+1,sysdate-1) and :p1_task_id is not null
这工作正常,但我想获取下一个/上一个工作日(下一个/上一个工作日)而不是 sysdate+1 和 sysdate-1。我尝试过类似的操作:
select next_day(sysdate, to_char(sysdate+1,'DAY')) from dual`
但无法继续。
请帮忙。
My query is somewhat like this:
select 1 from dual where :p1_task_date in (sysdate,sysdate+1,sysdate-1) and :p1_task_id is not null
This works fine, but I wanted to get next/previous working days (next/previous week days) instead of sysdate+1 and sysdate-1. I tried something like:
select next_day(sysdate, to_char(sysdate+1,'DAY')) from dual`
but cannot proceed with this.
Please help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
@Tawman 的答案会起作用,但我更喜欢这种方法的可读性:
正如其他人所说,这只能用于排除周末,而不是假期。
@Tawman's answer will work, but I prefer this method for readability:
As everyone else has stated, this will only work to exclude weekends, not holidays.
在不考虑假期的情况下,您可以使用 DECODE 函数使用星期几来执行一些简单的日期数学运算:
只需将 SYSDATE 替换为包含要检查的日期的变量即可。 DECODE 使用星期几来确定从基准日期添加或减去多少天。
Without consideration for holidays, you can use the day of the week to perform some simple date math using the DECODE function:
Simply substitute SYSDATE with a variable containing the date to check. The DECODE is using the day of the week to determine how many days to add or subtract from the base date.
要使星期几的日期计算与区域设置无关,您可以使用 截断到ISO 周开始,其中总是星期一。
上一个工作日:
下一个工作日:
下面是完整的示例代码。
SQL Fiddle 测试
To make date calculations for days of week independent from locale settings you can use truncation to beginning of ISO week which always a Monday.
Previous working day:
Next working day:
Below is full example code.
SQL Fiddle test
我认为最好的方法是使用 dbms_scheduler 创建所有工作日的时间表。这样您就可以根据需要进行调整,并且您的代码永远不必更改。创建计划后,使用 dbms_scheduler.evaluate_calendar_string 函数计算下一个日期。这将在周一至周五进行,但您可以轻松地增强日程安排以删除假期:
好处是您还可以使用它在工作日自动执行作业。
我刚刚看到你也希望能够完成前一个工作日的工作。这对于时间表来说不太方便,但可以通过快速循环来完成。今天前两天开始,运行计划,看看结果是否在今天之前。如果没有备份,改天再做一次。重复此操作,直到找到前一个工作日。
I think the best way to do this is use dbms_scheduler to create a schedule of all your work days. That way you can adjust it as needed and your code never has to change. Once you have the schedule created, use the dbms_scheduler.evaluate_calendar_string function to calculate the next date. This will do Monday-Friday but you could easily enhance the schedule to also remove holidays:
A bonus is you can also use it to automatically execute jobs on work days.
I just saw you also wanted to be able to do the previous workday. That's not as convenient with the schedule but can be done with a quick loop. Start a two days before today, run the schedule, and see if the result is before today. If not back up another day and do it again. Repeat until you find the previous workday.
此过程允许您获取不包括假期和周末的工作日:
This procedure allows you to get work days exclude holidays and weekends:
仅跳过周末:
to skip only weekends: