2017-10-12 1 views
0

Oracle (SQL) - Ich habe 3 verfügbare Daten in einem Monat (1., 10. und 25.). Ich brauche eine Abfrage, um anhand des Datums, an dem meine Abfrage ausgeführt wurde, den am nächsten kommenden der drei Daten herauszufinden. Zum Beispiel, wenn ich die Abfrage auf 4., ich sollte 10. als mein Ergebnis, wenn ich am 12. laufen, sollte das Ergebnis 25. und wenn ich am 27. laufen, sollte das Ergebnis der 01. des nächsten Monats sein. Ich kämpfe mit der Logik. Bitte helfen ..Nächstes Datum zu einem bestimmten Datum - SQL Oracle

+0

Welche Version der Datenbank? – APC

+0

Immer diese 3 Daten? Verwenden Sie einen 'case' Ausdruck. – jarlh

+0

Wie kommt der 27. dem 1. Folgemonat näher als dem 25.? ' – jarlh

Antwort

0

Ich glaube, das viel effizienter und einfacher als die anderen Lösungen ist.

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

Vielen Dank. –

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

Vielen Dank –

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

Vielen Dank –

0

Bei der Verwendung von PL SQL ist eine Option, verwenden Sie dann die Abfrage wie folgt:

`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

Vielen Dank –

Verwandte Themen