Wie kann ich Datums- und Zeitwerte mit reduzierter Genauigkeit in einem PostgreSQL-Typ speichern und sie als Datums- und / oder Zeitwerte verhalten lassen ?
ISO 8601 ermöglicht Datumswerte mit reduzierter Genauigkeit. '1964', '1964-05', '1964-05-02' sind alle gültigen Darstellungen eines Wertes mit zunehmender Genauigkeit. Die Python-Datetime-Typen ermöglichen auf diese Weise auch Werte mit reduzierter Genauigkeit.
Native PostgreSQL-Zeittypen erlauben keine reduzierte Genauigkeit
Im nativen Datumstyp muss jedes Element eines Datums vorhanden sein, sonst wird der Wert abgelehnt. Das Einstellen der Elemente unterhalb der gewünschten Genauigkeitsstufe auf '00' schlägt ebenfalls fehl.
=> SELECT CAST('1964-05-02' AS DATE);
date
------------
1964-05-02
(1 row)
=> SELECT CAST('1964-05' AS DATE);
ERROR: invalid input syntax for type date: "1964-05"
LINE 1: SELECT CAST('1964-05' AS DATE);
^
=> SELECT CAST('1964' AS DATE);
ERROR: invalid input syntax for type date: "1964"
LINE 1: SELECT CAST('1964' AS DATE);
^
=> SELECT CAST('1964-00-00' AS DATE);
ERROR: date/time field value out of range: "1964-00-00"
LINE 1: SELECT CAST('1964-00-00' AS DATE);
^
HINT: Perhaps you need a different "datestyle" setting.
Erwartetes Verhalten für einen Datums- und / oder Zeittyp mit reduzierter Genauigkeit
Gibt es eine einfache Standardmethode, um die Eingabe von ISO 8601-Datumswerten mit reduzierter Genauigkeit in einen PostgreSQL-Datums- und / oder Zeittyp zu unterstützen?
Es ist möglich, einen Typ dafür zu erstellen, aber ich weiß nicht wie. Natürlich müssen die Werte im Bereich überprüft werden, Zeitzonen behandelt und alle anderen nützlichen Funktionen der integrierten Typen sinnvoll mit anderen Zeitwerten verglichen werden.
Was ich erwarte ist, dass, genau wie der Wert '1964-05-02' sich auf das gesamte Intervall zwischen 00:00:00 an diesem Tag bis 00:00:00 am nächsten Tag bezieht, ein Wert mit reduzierter Genauigkeit einfach a darstellen würde größeres Intervall: "1962-05" bezieht sich auf das gesamte Intervall zwischen 00:00:00 Anfang Mai 1962 und 00:00:00 am ersten Juni 1962.
Ein Beispiel für das, was ich sehen möchte:
=> SELECT CAST('1964-05-02 00:00' AS TIMESTAMP) = CAST('1964-05-02 00:00:00' AS TIMESTAMP);
?column?
----------
t
(1 row)
=> SELECT CAST('1964-05' AS TIMESTAMP) = CAST('1964-05-02' AS TIMESTAMP);
?column?
----------
t
(1 row)
Derzeit verhält sich Ersteres wie oben; Letzterer beschwert sich über "ungültige Eingabesyntax für Typ Zeitstempel". Meines Erachtens handelt es sich bei beiden Fällen um Werte mit reduzierter Genauigkeit, die sich im Vergleich zu Werten mit feinerer Genauigkeit vernünftig verhalten.
Die Bedeutung von 1964-05
in ISO 8601 umfasst die genaueren Werte 1964-05-02
und 1964-05-02 18:27
und 1964-05-23
. Also sollten diese alle gleich vergleichen.
quelle
true
wann die Zeitstempel "möglicherweise" gleich sind (unter Berücksichtigung der Genauigkeit)?1964-05
in ISO 8601 umfasst die genaueren Werte1964-05-02
und1964-05-02 18:27
und1964-05-23
. Also sollten diese alle gleich vergleichen.Antworten:
Ich habe in der Vergangenheit CHAR und VARCHAR verwendet und die fehlenden Teile durch Fragezeichen oder Bindestriche ersetzt. Fragezeichen bedeuten "nicht bekannt" und Bindestriche bedeuten "nicht zutreffend". Dies erwies sich für die Benutzer (Sekretäre und Rechtsanwaltsanwärter in komplexen Rechtsstreitigkeiten) als intuitiv genug, für die Anwälte als flexibel genug und sinnvoll sortiert.
Schließen Sie Ihre Deklaration und CHECK-Einschränkungen in CREATE DOMAIN oder CREATE TYPE ein, um die Wartung zu vereinfachen. CREATE DOMAIN erfordert keine zusätzliche Codierung. CREATE TYPE erfordert Support-Funktionen, die in einer einfachen Sprache geschrieben sind.
quelle
create type
erfordert jedoch keine Unterstützungsfunktionen in einer einfachen Sprache, es sei denn, Sie erstellen einen neuen Basistyp. Ein zusammengesetzter Typ von adatetime
und eine Präzisionenum
zum Beispiel.create domain
kann dann um den Typ gewickelt werden, umcheck
Einschränkungen hinzuzufügen . Ich persönlich möchte, dass die DB die Komplexität von Zeitzonen, Schaltjahren usw. bewältigt, wenn sie erforderlich sind. Daher würde ich es vorziehen, die mitgelieferten Typen zu verpacken.create domain
kann keinen zusammengesetzten Typ als Basis verwenden .create type
, können Sie Ausdrücke des Formulars(DATE '1964-??-??' < 'DATE 1964-05-??')
immer als WAHR auswerten lassen. Was Sie nicht tun können, ist alle davon zu überzeugen, dass es sinnvoll ist, dies zu tun. Und das ist wahrscheinlich der Grund, warum PostgreSQL, das native Unterstützung für etwa 3 Dutzend Datentypen bietet, diese Art von Datentyp nicht nativ unterstützt.Nein, die Intervall - Typ unterstützt reduzierter Genauigkeit , aber keiner der anderen Datum / Zeit - Typen tun.
Mit Postgres können Sie Ihre eigenen rollen,
create type
aber leider können dem Typ keine Einschränkungen hinzugefügt werden, was die Nützlichkeit in diesem Szenario einschränkt. Das Beste, was ich mir einfallen lassen kann, ist, dass Sie die Überprüfungsbeschränkungen für jedes Feld wiederholen, in dem derfuzzy
Typ verwendet wird:--edit - ein Beispiel für einen Gleichheitsoperator:
Beispielabfrage:
quelle