簡體   English   中英

最接近日期到給定日期-SQL Oracle

[英]Closest Date to a given date - SQL Oracle

Oracle(SQL)-我在一個月(1號,10號和25號)中有3個可用日期。 我需要一個查詢來根據執行查詢的日期找出3個日期中最接近的日期。 例如,當我在4日運行查詢時,我的結果應該是10日;當我在12日運行時,結果應該是25日;當我在27日運行時,結果應該是下個月的01日。 我在邏輯上掙扎。 請幫忙..

with
     inputs ( dt ) as (
       select to_date( '03/24/2015 11:30:00', 'mm/dd/yyyy hh24:mi:ss') from dual union all
       select to_date( '08/03/2016 07:15:00', 'mm/dd/yyyy hh24:mi:ss') from dual union all
       select to_date( '02/29/2016 22:30:00', 'mm/dd/yyyy hh24:mi:ss') from dual
     )
-- End of simulated inputs (for testing only, not part of the solution).
-- SQL query begins BELOW THIS LINE. Use your actual table and column names.
select dt,
       case when extract(day from dt) < 10 then trunc(dt, 'mm') + interval  '9' day
            when extract(day from dt) < 25 then trunc(dt, 'mm') + interval '24' day
            else add_months(trunc(dt, 'mm'), 1)
       end  as next_std_dt
from   inputs;

DT                   NEXT_STD_DT       
-------------------  -------------------
03/24/2015 11:30:00  03/25/2015 00:00:00
08/03/2016 07:15:00  08/10/2016 00:00:00
02/29/2016 22:30:00  03/01/2016 00:00:00
WITH mytable(dt) AS
  (SELECT '01'
   FROM dual
   UNION ALL SELECT '10'
   FROM dual
   UNION ALL SELECT '25'
   FROM dual),
     given_dates AS
  (SELECT Trunc (To_date (dt || To_char(sysdate, 'MMYYYY'), 'DDMMYYYY')) dt,
          Trunc(sysdate) cdate
   FROM mytable),
     comp AS
  (SELECT cdate,
          CASE
              WHEN ABS (cdate - dt) < ABS (cdate - Add_months (dt, 1)) THEN dt
              ELSE Add_months (dt, 1)
          END dt_comp
   FROM given_dates)
SELECT dt_comp closest_date
FROM
  (SELECT dt_comp,
          rank() OVER (
                       ORDER BY ABS (cdate - dt_comp)) rn
   FROM comp)
WHERE rn = 1;

如果可以選擇使用PL SQL,則按以下方式使用查詢:

`DECLARE
   curr_month        CHAR(2);
   curr_year         CHAR(4);
   future_date       DATE;
BEGIN
   select to_char(sysdate, 'MM') INTO curr_month from dual;
   select to_char(sysdate, 'YYYY') INTO curr_year from dual;
   future_date := TO_DATE('12' ||  curr_month || curr_year, 'DD/MM/YYYY');
   IF (SYSDATE > future_date) THEN
        {..whatever you want to do...}
   ELSIF (SYSDATE > future_date2) THEN
        {..whatever you want to do...}
   END IF;
END;`

我相信這比其他解決方案更有效,更簡單。

WITH
    possible_dates
    AS
        -- generate the three available dates for the current month
        (SELECT TRUNC (SYSDATE, 'MM') available_date
           FROM DUAL
         UNION ALL
         SELECT TRUNC (SYSDATE, 'MM') + 9
           FROM DUAL
         UNION ALL
         SELECT TRUNC (SYSDATE, 'MM') + 24
           FROM DUAL
         UNION ALL
         SELECT ADD_MONTHS (TRUNC (SYSDATE, 'MM'), 1)
           FROM DUAL),
    delta
    AS
        -- calculate the distance of those available dates
        (SELECT (available_date - SYSDATE) diff, available_date
           FROM possible_dates)
SELECT *
  FROM delta
 WHERE diff = (SELECT MIN (diff)
                 FROM delta
                WHERE diff >= 0);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM