2016-05-31 31 views
-1

Ich habe eine Situation, in der ich eine Veranstaltung jeden Tag zwischen 23:00 Uhr bis zum nächsten Tag 01:00 Uhr erhöhen muss. Meine Tabelle hat ein Datum von Datum, die aussehen wird:Finden Sie die aktuelle Zeit zwischen zwei Feldern in Oracle

Start date   | EndDate 
31-05-2016 23:00:00 | 01-06-2016 01:00:00 

Schon die Datenbank wie diese konzipiert und Anwendungen sind zu Hause ist. Jetzt habe ich versucht, die Daten mit BETWEEN Anweisung zu bekommen, aber nichts funktioniert, wie ich brauche, da das ENDDate am nächsten Morgen ist.

Kann jemand sagen, wie man diese Daten richtig extrahiert.

Meine ORACLE Abfrage

SELECT COUNT(*) INTO P_OUTPUT FROM MAINTENANCE_LOG WHERE  
NVL(RECCURING_TYPE,'O')='D' AND ACTIVE_STATUS='Y' AND 
TO_CHAR(SYSDATE,'HH24MISS') BETWEEN TO_CHAR(START_DATE,'HH24MISS') AND TO_CHAR(END_DATE,'HH24MISS'); 

Ich habe versucht, wieder das bisher Umwandlung, aber es ist auch nicht mit dem EndDate arbeiten.

Update: In meiner Anforderung muss ich nur überprüfen, ob die aktuelle Zeit zwischen dem Startdatum oder der Endzeit liegt. Ich muss diese Abfrage jeden Tag ausführen und es sollte eine Aktivität zwischen 23:00 und 1:00 eines jeden Tages machen.

Hinweis: Wenn ich die Abfrage von am 31-05-2015 ausführen, werde ich wahr/falsch erhalten. Aber, wenn ich am nächsten Tag in der Nacht renne, werde ich nur falsch werden, da das EndDate schon vorbei ist. Also kann ich die normale Datumsabfrage nicht verwenden.

+0

Warum sind Sie ein Datumsfeld to_charing und mit zwischen? Tue sie nicht. Vergleichen Sie einfach sysdate zwischen start_date und end_date ... Sie fordern die Engine auf, TEXT-Werte zu vergleichen. was sollte nicht ondates getan werden ... – xQbert

+1

Was ist über 'sysdate zwischen Startdatum und Enddatum? –

+0

Warum mache ich ein To_CHAR ist, obwohl meine Daten ein Datum haben Ich muss nur überprüfen, die aktuelle Zeit ist zwischen 23:00 und 01:00 Uhr. Es sollte mir eine Anzahl (*) basierend darauf geben. – smilu

Antwort

1
SELECT COUNT(*) 
INTO P_OUTPUT 
FROM MAINTENANCE_LOG 
WHERE RECCURING_TYPE = 'D' 
AND ACTIVE_STATUS = 'Y' 
AND (SYSDATE - TRUNC(SYSDATE) BETWEEN START_DATE - TRUNC(START_DATE) 
             AND END_DATE - TRUNC(START_DATE) 
     OR 
     SYSDATE - TRUNC(SYSDATE) BETWEEN START_DATE - TRUNC(END_DATE) 
             AND END_DATE - TRUNC(END_DATE) 
     ) 
0

Sie müssen keine Datumsfelder konvertieren nur verkohlen, Daten verwenden und BETWEEN clausule Ihr wählen zu erreichen:

SELECT COUNT(*) INTO P_OUTPUT 
FROM MAINTENANCE_LOG 
WHERE  
    NVL(RECCURING_TYPE,'O')='D' AND 
    ACTIVE_STATUS='Y' AND 
    SYSDATE BETWEEN START_DATE AND END_DATE; 

Auf jeden Fall in Frage, ... Sie YYYYMMDD hinzufügen könnte ... aber bitte tue es nicht, wenn du Datumsfelder verwendest.

TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') BETWEEN 
TO_CHAR(START_DATE,'YYYYMMDDHH24MISS') AND 
TO_CHAR(END_DATE, 'YYYYMMDDHH24MISS') 
+0

Ich habe diese gemacht. Aber meine Anforderung ist, nur die Zeit zu extrahieren und die aktuelle Zeit mit der Start- und Endzeit zu vergleichen. Sagen wir heute, wenn ich die Abfrage ausführe, wird es wahr, da es der 31. Mai ist. Aber morgen, wenn ich das Enddatum laufen lasse, ist es schon vorbei. – smilu

1

Wenn ich die Frage bekommen, wollen Sie von Daten, um die Zeiten separat zu behandeln. Das heißt, 2016-MAI-31 23:00:00 sollte als nur 23:00:00 behandelt werden und 2016-JUN-01 01:00:00 sollte als nur 01:00:00 behandelt werden und diese zwei Mal als behandeln eine Auswahl? Wenn ich also eine Zeit von 23:47:43 oder 00:23:11 betrachte, würden beide innerhalb der Reichweite liegen, aber Zeiten wie 22:56:34 und 01:34:52 wären außerhalb der Reichweite?

Um mit einem Datentyp DATE zu gehen, erstreckt sich Ihr Bereich über zwei Daten, sodass Sie Daten auf den Zeiteingabewert setzen müssen, sodass eine Uhrzeit wie 00:23:11 als JJJJ-MM-TT 00 betrachtet wird: 23:11 und dieses Datum/diese Uhrzeit zwischen Ihre beiden Datum/Zeiten (START_DATE und END_DATE) zu setzen.

In Ihrem Beispiel würde 2016-JUN-01 00:23:11 funktionieren aber 2016-MAI-31 00: 23:11 würde nicht. Ähnlich für 23:47:23, 2016-MAI-31 23:47:23 würde funktionieren aber 2016-JUN-01 23:47:23 würde nicht.

Grundsätzlich könnte die Regel wie folgt: Wenn die Zeit, die Sie testen wollen, eine Stunde hat < 12 (mittags), das Datum aus dem END_DATE hängen, sonst (Stunde> = 12) anhängen das Datum aus dem START_DATE und vergleichen Sie das Ergebnis mit den Datum/Uhrzeit in START_DATE und END_DATE.

Vielleicht so etwas (ich simulieren Ihre Start-/Enddaten Tabelle mit einer Abfrage hier):

WITH test_data AS 
(SELECT '00:23:11' as time_char 
    FROM dual 
UNION ALL 
SELECT '23:47:23' as time_char 
    FROM dual 
UNION ALL 
SELECT '22:56:34' as time_char 
FROM dual 
UNION ALL 
SELECT '01:34:52' as time_char 
    FROM dual 
UNION ALL 
SELECT '12:34:52' as time_char 
    FROM dual 
UNION ALL 
SELECT '23:00:00' as time_char 
    FROM dual 
UNION ALL 
SELECT '01:00:00' as time_char 
    FROM dual 
UNION ALL 
SELECT '22:59:59' as time_char 
    FROM dual 
UNION ALL 
SELECT '01:0:01' as time_char 
    FROM dual 
) 
SELECT test_data.time_char, start_end_table.* 
FROM (SELECT TO_DATE('2016-MAY-31 23:00:00', 'YYYY-MON-DD HH24:MI:SS') as start_date 
      , TO_DATE('2016-JUN-01 01:00:00', 'YYYY-MON-DD HH24:MI:SS') as end_date 
     FROM dual 
    ) start_end_table 
    FULL OUTER JOIN 
    test_data 
    ON 
    CASE WHEN TO_NUMBER(SUBSTR(test_data.time_char, 1, 2)) < 12 
      THEN TO_DATE(TO_CHAR(start_end_table.end_date, 'YYYYMMDD')||test_data.time_char, 'YYYYMMDDHH24:MI:SS') 
      ELSE TO_DATE(TO_CHAR(start_end_table.start_date, 'YYYYMMDD')||test_data.time_char, 'YYYYMMDDHH24:MI:SS') 
     END 
     BETWEEN start_end_table.start_date AND start_end_table.end_date 

TIME_CHAR START_DATE    END_DATE 
00:23:11 2016-MAY-31 23:00:00 2016-JUN-01 01:00:00 
23:47:23 2016-MAY-31 23:00:00 2016-JUN-01 01:00:00 
23:00:00 2016-MAY-31 23:00:00 2016-JUN-01 01:00:00 
01:00:00 2016-MAY-31 23:00:00 2016-JUN-01 01:00:00 
01:34:52   (null)     (null) 
01:0:01   (null)     (null) 
22:59:59   (null)     (null) 
22:56:34   (null)     (null) 
12:34:52   (null)     (null)