简体   繁体   English

Oracle SQL 除了确定的天数外,计算到最接近的每月 1 日

[英]Oracle SQL calculating to the nearest 1st of the month IN ADDITION to a determined amount of days

I have been trying to create an Oracle SQL statement that can work based on first of the month conditions.我一直在尝试创建一个 Oracle SQL 语句,该语句可以根据月初的条件工作。 Dates are murdering me because their formatting is very specific.日期正在谋杀我,因为它们的格式非常具体。

Essentially, if a date isn't the first of the month I need to count the days until the next first of the month.本质上,如果某个日期不是本月的第一天,我需要计算直到下一个月初的天数。

So lets say if I had a wait period of 54 days and 54 days didn't land on a first of the month condition, I need to add the remaining days until the next first of the month.因此,假设我有 54 天的等待期,并且 54 天没有达到月初的条件,我需要将剩余的天数添加到下个月的第一天。 So it'd be 54 days PLUS the remaining days until the next first day of the month.所以这将是 54 天加上剩余的天数,直到该月的下一个第一天。 I'm using the below statement to calculate days remaining for me.我正在使用以下语句来计算我的剩余天数。

current_date and sysdate I've been using interchangably. current_date 和 sysdate 我一直在互换使用。

ROUND((ENROLLDT-CURRENT_DATE + WAITPRD),1) AS WAIT_DAYS)

Enrolldt is a date someone "enrolls" for a service - sysdate/current_date so we can get the amount of time passed by already + waitprd [which is "activation wait period after enrollment" that is an integer value]. Enrolldt 是某人“注册”服务的日期 - sysdate/current_date,因此我们可以获得已经经过的时间 + waitprd [这是“注册后的激活等待期”,即 integer 值]。 So for example, someone can enroll on 5/5 with a 90 day wait period which would be August 3rd but if they have a first of the month condition it would be September 1st.因此,例如,某人可以在 5 月 5 日注册,等待期为 90 天,即 8 月 3 日,但如果他们有一个月的第一天条件,那就是 9 月 1 日。 So if we were to do today 5/7, it'd be 88 days + the new first of the month calculation from there.所以如果我们今天 5 月 7 日做,那就是 88 天 + 从那里开始计算的新的月初。

I've also been playing with ROUND((((ADD_MONTHS(TRUNC(SYSDATE, 'MM'), +1)))-SYSDATE),1) That's to calculate the remaining days from now, to the next first of the month but something isn't clicking when I try to combine these together because date formatting is new to me (obviously).我也一直在玩ROUND((((ADD_MONTHS(TRUNC(SYSDATE, 'MM'), +1)))-SYSDATE),1)那是计算从现在到下一个月的剩余天数但是当我尝试将它们组合在一起时,有些东西没有点击,因为日期格式对我来说是新的(显然)。

Any help or direction is greatly appreciated.非常感谢任何帮助或指导。

Rather than trying to work out a variable number of days to adjust by, you can manipulate the end of the wait period using trunc() and add_months() (or interval addition):您可以使用trunc()add_months() (或间隔加法)来操纵等待期的结束,而不是尝试计算出可变天数来调整:

add_months(trunc(enrolldt + waitprd - 1, 'MM'), 1)

So with your example enrol date of 2021-05-05 and wait period of 90 days:因此,您的示例注册日期为 2021-05-05,等待期为 90 天:

  • enrolldt + waitprd = 2021-08-03注册时间 + waitprd = 2021-08-03
  • enrolldt + waitprd - 1 = 2021-08-02注册dt + waitprd - 1 = 2021-08-02
  • trunc(enrolldt + waitprd - 1, 'MM') = 2021-08-01 trunc(enrolldt + waitprd - 1, 'MM') = 2021-08-01
  • add_months(trunc(enrolldt + waitprd - 1, 'MM'), 1) = 2021-09-01 add_months(trunc(enrolldt + waitprd - 1, 'MM'), 1) = 2021-09-01

The -1 is there to handle when the wait period ends on the first of the month.当等待期在每月的第一天结束时,-1 可以处理。 For example, if the enrol date was 2021-04-08 and wait period was 54:例如,如果注册日期为 2021-04-08,等待期为 54:

  • enrolldt + waitprd = 2021-06-01注册时间 + waitprd = 2021-06-01
  • enrolldt + waitprd - 1 = 2021-05-31注册dt + waitprd - 1 = 2021-05-31
  • trunc(enrolldt + waitprd - 1, 'MM') = 2021-05-01 trunc(enrolldt + waitprd - 1, 'MM') = 2021-05-01
  • add_months(trunc(enrolldt + waitprd - 1, 'MM'), 1) = 2021-06-01 add_months(trunc(enrolldt + waitprd - 1, 'MM'), 1) = 2021-06-01

Then, if I'm following that part, your wait calculation is just:然后,如果我关注那部分,您的等待计算只是:

add_months(trunc(enrolldt + waitprd - 1, 'MM'), 1) - trunc(sysdate) 

giving 177 and 25 respectively for those two examples when run today.今天运行时,这两个示例分别给出 177 和 25。

db<>fiddle demo with some sample values covering month end/start. db<>fiddle 演示,其中包含一些涵盖月末/开始的示例值。

You could use a case expression to decide whether to adjust based on whether it's already on the first, but I think it's simpler to just always do it.您可以使用案例表达式来决定是否根据它是否已经在第一个进行调整,但我认为总是这样做更简单。


As @mathguy pointed out, if you aren't already filtering them out somehow then some past enrol date/wait period calculations could give you a negative result, and you can use greatest() to avoid negative numbers, replacing them with zero:正如@mathguy 指出的那样,如果您还没有以某种方式将它们过滤掉,那么过去的一些注册日期/等待期计算可能会给您带来负面结果,您可以使用greatest()来避免负数,将它们替换为零:

greatest(0, add_months(trunc(enrolldt + waitprd - 1, 'MM'), 1) - trunc(sysdate))

db<>fiddle with an example. db<> 摆弄一个例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM