如何在日期之后找到下个月的第X个月

时间:2016-11-22 10:12:25

标签: sql oracle

我有两个参数:

  1. 约会(例如:2016年11月22日)
  2. 一个天数(例如:25)
  3. 我希望在2016年11月22日之后找到下一个月25日:25/11/2016

5 个答案:

答案 0 :(得分:1)

select trunc(date '2016-11-22', 'month') + 25
from dual;

trunc(date '2016-11-22', 'month')将在当月的第一天返回,+ 25将添加所需的25天。

如果第二个参数的含义取决于"比较"约会,你可以做这样的事情:

select case 
          when extract(day from date '2016-11-22') >= 25 then 
             add_months(trunc(date '2016-11-22', 'month'), 1) + 25 
          else trunc(date '2016-11-22', 'month') + 25
        end as next_date
from dual;

当然你会替换日期的硬编码值和"数字"带变量或列值的天数。

这个例子:

with sample_data (the_date, num_days) as (
   select date '2016-11-22', 25 from dual union all
   select date ' 2016-11-26', 22 from dual union all
   select date ' 2016-11-26', 3 from dual
)
select the_date, num_days, 
       case 
          when extract(day from the_date) >= num_days then 
             add_months(trunc(the_date, 'month'), 1) + num_days - 1
          else trunc(the_date, 'month') + num_days - 1
        end as next_date
from sample_data;

将返回:

THE_DATE    | NUM_DAYS | NEXT_DATE  
------------+----------+------------
2016-11-22  |       25 | 2016-11-25 
2016-11-26  |       22 | 2016-12-22 
2016-11-26  |        3 | 2016-12-03 

答案 1 :(得分:1)

它可以解决您的问题:

 select 
    (
    case 
      when trunc (:yourdate-trunc(:yourdate,'month'))+1 <:urNum then
      trunc(:yourdate,'month')+:urNum-1
        else
         trunc(last_day(:yourdate))+:urNum
          end) 
      from dual;

答案 2 :(得分:0)

您可以使用

LAST_DAY(<<a date>>) + <<a day number>> + 1

LAST_DAY为您提供给予的最后一天,月份(e.i. 11月30日),然后添加1天以获得12月1日加上您的日期号码。

答案 3 :(得分:0)

你可以用这个

WITH tmp AS 
(
    SELECT TO_DATE('22/11/2016', 'DD/MM/YYYY') date_col FROM DUAL
)
SELECT 
    CASE WHEN TO_CHAR(date_col,'DD') > '25' 
        THEN TO_DATE('25' || TO_CHAR(ADD_MONTHS(date_col, 1), '/MM/yyyy'), 'DD/MM/YYYY')  
        ELSE TO_DATE('25' || TO_CHAR(date_col, '/MM/yyyy'), 'DD/MM/YYYY') END date_col_new
FROM tmp;

如果您的输入(25)是数字,则可以使用TO_CHAR(your_input)代替'25'

答案 4 :(得分:0)

这是一种方式:

WITH dates AS (SELECT to_date('30/11/2015', 'dd/mm/yyyy') dt FROM dual UNION ALL
               SELECT to_date('03/11/2015', 'dd/mm/yyyy') dt FROM dual UNION ALL
               SELECT to_date('31/10/2015', 'dd/mm/yyyy') dt FROM dual UNION ALL
               SELECT to_date('29/11/2015', 'dd/mm/yyyy') dt FROM dual UNION ALL
               SELECT to_date('31/01/2016', 'dd/mm/yyyy') dt FROM dual),
       dom AS (SELECT 25 day_of_month FROM dual UNION ALL
               SELECT 31 day_of_month FROM dual UNION ALL
               SELECT 30 day_of_month FROM dual UNION ALL
               SELECT 03 day_of_month FROM dual UNION ALL
               SELECT 01 day_of_month FROM dual),
       res AS (SELECT dates.dt starting_dt,
                      dom.day_of_month,
                      add_months(TRUNC(dates.dt, 'mm'),
                                 CASE WHEN to_char(dates.dt, 'dd') >= dom.day_of_month
                                           THEN 1
                                      ELSE 0
                                 END) month_of_end_dt
               FROM   dates
                      CROSS JOIN dom)
SELECT starting_dt,
       day_of_month,
       month_of_end_dt + least(day_of_month, to_number(to_char(last_day(month_of_end_dt), 'dd'))) - 1 next_date
FROM   res
ORDER BY starting_dt, day_of_month;

STARTING_DATE DAY_OF_MONTH NEXT_DATE
------------- ------------ ----------
31/10/2015               1 01/11/2015
31/10/2015               3 03/11/2015
31/10/2015              25 25/11/2015
31/10/2015              30 30/11/2015
31/10/2015              31 30/11/2015
03/11/2015               1 01/12/2015
03/11/2015               3 03/12/2015
03/11/2015              25 25/11/2015
03/11/2015              30 30/11/2015
03/11/2015              31 30/11/2015
29/11/2015               1 01/12/2015
29/11/2015               3 03/12/2015
29/11/2015              25 25/12/2015
29/11/2015              30 30/11/2015
29/11/2015              31 30/11/2015
30/11/2015               1 01/12/2015
30/11/2015               3 03/12/2015
30/11/2015              25 25/12/2015
30/11/2015              30 30/12/2015
30/11/2015              31 30/11/2015
31/01/2016               1 01/02/2016
31/01/2016               3 03/02/2016
31/01/2016              25 25/02/2016
31/01/2016              30 29/02/2016
31/01/2016              31 29/02/2016

这样做是首先通过比较你所追踪的日期与被比较的日期来找出新日期的月份。 (即,如果您想要到达的日期已经过了开始日期的那一天,请在月份中添加一个,否则不添加任何内容。)

一旦你有了这个,就可以添加你想要达到的天数。

我假设如果月份没有完整的天数(例如,2月,4月,6月,9月,11月),那么您将需要该月的最后一天。

因此,我们会选择较低者 - 本月的最后一天或您想要去的那一天。我们必须从该结果中减去一个,因为我们希望将该月的第一个包含在计数中。