2013-10-19 3 views
66

Ich habe ein seltsames Szenario erlebt, wenn ich Daten in postgresql (Version 9.2.4 in Windows) verglichen habe. Ich habe eine Spalte in meiner Tabelle sagen update_date mit dem Typ 'Zeitstempel ohne Zeitzone'. Der Kunde kann über dieses Feld nur mit Datum (d. H. 2013-05-03) oder Datum mit Uhrzeit (d. H. 2013-05-03 12:20:00) suchen. Diese Spalte hat den Wert als Zeitstempel für alle aktuellen Zeilen und hat den gleichen Datumsteil (2013-05-03), aber den Unterschied in der Zeit.Wie werden Datumsangaben in Datetime-Feldern in Postgresql verglichen?

Wenn ich über diese Spalte vergleiche, bekomme ich unterschiedliche Ergebnisse. Wie die folgenden:

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-03' -> No results 

select * from table where update_date >= '2013-05-03' AND update_date < '2013-05-03' -> No results 

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-04' -> results found 

select * from table where update_date >= '2013-05-03' -> results found 

Meine Frage ist, wie kann ich die erste Abfrage möglich Ergebnisse zu bekommen, ich meine, warum die dritte Abfrage funktioniert, aber nicht die ersten?

Kann mir jemand dabei helfen? Danke im Voraus.

+1

was ist die Frage hier? –

+0

Thnaks. Ich habe meine Frage bearbeitet. "Meine Frage ist, wie kann ich die erste Abfrage möglich machen, um Ergebnisse zu erhalten, ich meine, warum die 3. Abfrage funktioniert, aber nicht die erste?" – user2866264

Antwort

122

@Nicolai korrekt über Gießen und warum Die Bedingung ist falsch für alle Daten. Ich schätze, Sie bevorzugen die erste Form, weil Sie eine Datumsmanipulation in der Eingabe-Zeichenfolge vermeiden möchten, richtig? Sie müssen keine Angst haben:

SELECT * 
FROM table 
WHERE update_date >= '2013-05-03'::date 
AND update_date < ('2013-05-03'::date + '1 day'::interval); 
+0

Vielen Dank für Ihre Antwort. Es funktioniert, indem Sie Ihrer Antwort folgen. – user2866264

+0

Ist diese Syntax (''2013-05-03' :: date' und' '1 day' :: interval') PostgreSQL-spezifisch? –

+2

@FrozenFlame ja ist es. die Standardsyntax würde "CAST ('2013-05-03' AS DATE) + CAST ('1 Tag' AS INTERVAL) '(IIRC) sein. YMMV über die Existenz und das Verhalten von 'DATE' und' INTERVAL'. –

18

Wenn Sie update_date >= '2013-05-03' vergleichen, werden Werte nach dem gleichen Typ konvertiert, um Werte zu vergleichen. Ihr "2013-05-03" wurde also an "2013-05-03 00:00:00" vergeben.

Also für UPDATE_DATE = '2013.05.03 14.45.00' Ihr Ausdruck wird das sein:

'2013-05-03 14:45:00' >= '2013-05-03 00:00:00' AND '2013-05-03 14:45:00' <= '2013-05-03 00:00:00' 

Dies ist immer false

Um dieses Problem zu lösen, werfen UPDATE_DATE zu date:

select * from table where update_date::date >= '2013-05-03' AND update_date::date <= '2013-05-03' -> Will return result 
+1

Das Übergeben jedes 'update_date' in der Tabelle im Vergleich mit dem Einzelwert des Abfrageparameters ist äußerst ineffizient und stellt sicher, dass der Server keine Indizes für diese Spalte verwenden kann. Ich bin versucht zu -1. –

+1

Ja, ich stimme zu, dass die Umwandlung jedes Werts ineffizient ist und Sie für diese Lösung -1 angeben können. Aber ich habe den Grund des Problems beschrieben und ein Beispiel gegeben, das das Problem aufzeigt. Jetzt weiß user2866264, warum seine Abfrage keine erwarteten Zeilen zurückgibt und entscheidet, welche Lösung für diesen Fall besser ist. – Nicolai

+0

@Nicolai: Vielen Dank für Ihre Antwort. Es funktioniert, indem Sie Ihrer Antwort folgen. Danke auch für die Erklärung. – user2866264

Verwandte Themen