2016-11-08 3 views
0

Ich habe folgendes TABLE.Sample1:Oracle SQL: Vergleich Extrahiert Date in Timestamp

Col1(varchar) | Col2(timestamp) 
--------------------------------------- 
A    | 08-NOV-16 09.59.52.000000000 AM 
B    | 08-NOV-16 10.05.12.000000000 AM 
C    | 09-NOV-16 10.05.12.000000000 AM 

Angenommen, ich möchte alle Zeilen ein Datum im Format DD MON YYYY gegeben werden.

Hier ist meine erste Abfrage:

SELECT * 
    FROM Sample1 
WHERE CAST(Col2 as DATE) = TO_DATE('8 NOV 2016','DD MON YYYY'); 

Ich bin neugierig, warum diese Abfrage funktioniert nicht auf Gleichheit (=) aber funktioniert auf Ungleichheiten (>, <, <=, >=, <>) . Vergleiche ich hier nicht die gleichen Datentypen?

Ich endete mit TO_CHAR Funktion, um diese Arbeit zu machen, aber es stellt sich die Frage, gibt es einen einfacheren oder direkteren Ansatz dazu?

SELECT * 
    FROM Sample1 
WHERE TO_CHAR(CAST(Col2 as DATE)) = TO_CHAR(TO_DATE('8 NOV 2016','DD MON YYYY')); 

Antwort

1

In Oracle ein DATE Wert hat noch eine Zeit. CAST(Col2 as DATE) wird das nicht ändern.

Sie können trunc() nutzen die Zeit Teil eines date (oder timestamp) zu 00:00:00 setzen, und Sie sollten keine Strings vergleichen, aber die Daten:

SELECT * 
FROM Sample1 
WHERE trunc(col2) = TO_DATE('8 NOV 2016','DD MON YYYY'); 

Aber ich empfehle dringend nicht Verwendung ein Datumsformat wie das. Es hängt von den NLS-Einstellungen des SQL Clients Programms ab und kann mit unterschiedlichen Spracheinstellungen fehlschlagen.

ich lieber mit ANSI SQL Datumsliterale:

SELECT * 
FROM Sample1 
WHERE trunc(col2) = DATE '2016-11-08'; 

In beiden Fällen wird das Datum eine Zeit von 00:00:00 hat, weil keine gegeben wurde und somit wird der Vergleich zu arbeiten.

Beachten Sie, dass trunc(col2) keinen Index für col2 verwenden kann. Wenn die Leistung wichtig ist, sollten Sie entweder eine Bereichsabfrage where col2 >= DATE '2016-11-08' and col2 < DATE '2016-11-09' verwenden oder einen funktionsbasierten Index unter trunc(col2) erstellen.