2017-10-12 95 views
0

Oracle(SQL) - 我在一个月(第1,10和25天)中有3个可用日期。我需要一个查询来根据执行我的查询的日期找出3个日期中最近的一个。例如,当我在第四次运行查询时,我应该得到第十名作为我的结果,当我在第12次运行时,结果应该是第25次,当我在第27次运行时,结果应该是下个月的第01次。 我正在努力与逻辑。请帮助..到给定日期的最近日期 - SQL Oracle

+0

哪个版本的数据库? – APC

+0

总是这3个日期?使用'case'表达式。 – jarlh

+0

27日如何接近下个月1日而不是25日? ' – jarlh

回答

0

我相信这是比其他解决方案更加简单高效。

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); 
+0

非常感谢。 –

0
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; 
+0

非常感谢你 –

1
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 
+0

非常感谢你 –

0

如果使用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;` 
+0

非常感谢你 –