didi60
Goto Top

Frage zu postgresql sql Abfrage auf Datum in Textform

Guten Tag,
in einer Tabelle ist ein Datum in einem Textfeld in der Form '20.07.2016' hinterlegt .
Ich würde gerne alle Sätze heraus selektieren die z.B. älter sind als 20160701
Bei mysql konnte ich das so umsetzen:
and (substr(anlage_datum,7,4) * 10000 + substr(anlage_datum,4,2) * 100 + substr(anlage_datum ,1,2)) < 20160701

Das funktioniert aber leider nicht bei postgresql.
Die Version ist 9.1

Hat hier jemand eine schnelle Lösung.

Im Voraus vielen Dank
mfg

Didi

Content-Key: 310336

Url: https://administrator.de/contentid/310336

Printed on: April 16, 2024 at 19:04 o'clock

Member: Biber
Solution Biber Jul 20, 2016 updated at 07:41:33 (UTC)
Goto Top
Moin didi60,

Zitat von @didi60:

Guten Tag,
in einer Tabelle ist ein Datum in einem Textfeld in der Form '20.07.2016' hinterlegt .
Ich würde gerne alle Sätze heraus selektieren die z.B. älter sind als 20160701
Du meinst vermutlich "kleiner als" ? Älter als 20 Millionen (Taler? Schäfchen? Pfandflaschen?) gibt es so nicht wirklich.
Bei mysql konnte ich das so umsetzen:
and (substr(anlage_datum,7,4) * 10000 + substr(anlage_datum,4,2) * 100 + substr(anlage_datum ,1,2)) < 20160701

Das funktioniert aber leider nicht bei postgresql.
Das ist eine ganz, ganz tolle Fehlerbeschreibung.
Allerdings bestimmt abgekupfert - hab ich hier schon oft gelesen.

Also: Lösungsvorschlag 1:
Du änderst in dem mySQL-Gestrunkele
...
and (substring (anlage_datum from 7 for 4) ||  substring (anlage_datum from 4 for 2) || substring(anlage_datum  from 1 for 2)) < '20160701'  

Lösungsstrategie 2:
  • Du konvertierst den Datumsstring mit to_date() in en Datum
  • und dieses Datum wieder zurück in einen Sting im Format 'YYYMMDD'
  • und vergleichst diesen String mit einem String

... and to_char( to_date(anlagedatum, 'DD.MM.YYYY') , 'YYYYMMDD') < '20160701'  

Grüße
Biber
P.S. Dir ist aber auch schon selbst aufgefallen, dass für dich ein Datum ein wichtiges Kriterium ist, du aber immer Strings und numbers miteinander vergleichen musst in deiner Tabelle?
Wäre für mich ein Anlass, mal kurz innezuhalten und über das Tabellendesign nachzusinnen.
Member: didi60
didi60 Jul 20, 2016 at 08:08:20 (UTC)
Goto Top
Danke schon mal für die Antworten.
Die Datenbank ist gegeben, da kann ich selber nichts verändern.
Wenn ich über Datum schreibe und da steht 20160701 dann sind das bestimmt auch Taler
Ich teste mal die Lösungsvorschläge.
Gruß
Didi
Member: didi60
didi60 Jul 20, 2016 at 08:14:55 (UTC)
Goto Top
Haben beide funktioniert.
Vielen Dank
Gruß
Didi
Member: Biber
Biber Jul 20, 2016 updated at 08:38:10 (UTC)
Goto Top
Moin didi60,

Zitat von @didi60:

Die Datenbank ist gegeben, da kann ich selber nichts verändern.
Na ja...

Wie du oben in deinem Beispiel siehst, führt das schnell dazu, mal eine Typkonvertierung zuviel oder zuwenig zu machen - das sind sowohl Sollbruchstellen für Performance-Optimierungen (Index-Nutzung wird unmöglich) wie auch für die Robustheit und Datenqualität von Abfragen.

Und wenn es den menschlichen Leser zu der Aussage bringt: "Ja nee, sieht doch jeder, dass die Zahl 20170701 eigentlich ein Datum ist und ich will halt alle Daten, die älter sind..-"
-> Nein, eine SQL-Engine sieht das nicht. Und deshalb ist es ähbäh.
Ich würde zumindest zumindest aus Gründen der Lesbarkeit die WHERE-Clause so schreiben:
... and to_date(anlage_datum, 'DD.MM.YYYY')  < to_date('20160701', 'YYYYMMDD')  
 -- bzw 
-- ... to_date(anlage_datum, 'DD.MM.YYYY')  < to_date('01.07 2016', 'DD.MM.YYYY')  
Dann sieht jeder, dass es hier um Datumvergleiche geht, es sind genausoviel Typkonvertierungen wie vorher und wenn die erste Typkonvertierung (String anlage_datum->date) knallt, dann steht da halt kein gültiges Datum drin.

In der ersten Abfrage-Variante mit SUBSTRING kann auch im Feld anlage_datum der String "Augsburg" oder "50 Cent" stehen, ohne dass es auffällt.

Grüße
Biber