Subtraktion von Datumsangaben in MariaDB

zachy

Aktiver Benutzer
Beiträge
35
Hallo ins Forum,

wie speichert MariaDB eigentlich intern Daten des Typs DATE ab? Die Frage resultiert aus folgendem Sachverhalt:

Angenommen, ich habe folgende Tabelle:

StartdatumEnddatum
01.01.202210.01.2022
01.06.201630.11.2017

Jetzt führe ich diese Abfrage durch:

SQL:
SELECT 
    *, 
    Enddatum - Startdatum AS "Einfache Subtraktion", 
    DATEDIFF(Enddatum, Startdatum) AS "Prüfspalte"
FROM tblDatumsangaben;

Das ist mein Ergebnis:

StartdatumEnddatumEinfache SubtraktionPrüfspalte
2022-01-012022-01-1099
2016-06-012017-11-3010529547

Die einfache Subtraktion führt in der ersten Zeile zum richtigen Ergebnis, in der zweiten Zeile aber nicht mehr.
Die Prüfspalte liefert für die zweite Zeile das korrekte Ergebnis, nämlich 547.

In Excel kann ich ja einfach Datumsangaben voneinander abziehen, da das Programm Datumsangaben als Tage seit dem 01.01.1900 speichert.
Ich kann nur vermuten, dass MariaDB Datumsangaben anders behandelt und daher die Subtraktion nicht das gewünschte Ergebnis liefert (zumindest nicht in der zweiten Zeile).

Kann mir jemand helfen?

Grüße
zachy
 
Werbung:
MariaDB unterstützt ein - für Datumswerte (so wie es im SQL Standard vorgesehen ist) schlichtweg nicht.

Aber MySQL/MariaDB zieht es in vielen Fällen vor, irgend etwas zurück zu liefern (auch wenn es Blödsinn ist) anstatt einen Fehler zu werfen (z.B. liefert 'hallo' - 'welt' die Zahl 0)
 
MSSQL sagt auch ganz klar das DATE nicht einfach addiert oder subtrahiert werden kann. Auch muss man bei datediff() die Einheit, hier Tage, mit angeben, von alleine passiert da gar nichts.

Dein Beispiel entspricht:
20171130 - 20160601 = 10529
Es wird also das Datum zur numerischen Zeichenkette zur Zahl und das wird subtrahiert. Das sagt erstmal nichts über die "interne Speicherweise" von DATE aus sondern vielmehr darüber das MariaDB hier einfach eine Subtraktion versucht in dem es aus dem Datum eine Zahl macht.
 
Ich finde es sehr angenehm, dates zu addieren oder zu subtrahieren oder Zahlen zu Dates zu addieren. Die DB muss es halt können.
Genau genommen nicht nur angenehm, sondern sogar intuitiv und "pragmatisch". Anders jedenfalls als die Interval Funktion.
MS Perspektiven dürften maximal für MS selbst gelten.
 
Ich sage nicht das MS hier einen Standard vorgibt, nur das MS die Subtraktion von Datumswerten direkt ablehnt. Ich sehe das auch als gute Vorgehensweise an, die Subtraktion ist ja unspezifisch weil nicht klar ist, welches Ergebnis erwartet wird. Selbiges gilt meiner Meinung nach für datediff() ohne Interval Angabe.

Was diesen Fall mit MariaDB angeht so wird die "Einfache Subtraktion" ebenfalls korrekt durchgeführt. Die Erwartungshaltung war nur falsch.
 
Ich habs mal nach gelesen:
http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt Seite 34
Wenn ich das richtig deute wäre das Ergebnis von MariaDB hier falsch, es müsste ein Interval ausgegeben werden und 10529 ist kein gültiges Interval.

MSSQL weigert sich ein Interval auszugeben solange es nicht über Funktionen wie datediff() gesagt bekommt welche Einheit das Interval haben soll. Ob das jetzt falsch ist und einfach ein beliebiges Interval auszugeben ist (Tage würde sich ja anbieten) oder ob das dennoch Standard-konform ist überlasse ich jedem selbst.
 
Wird langsam etwas off-topic, aber:

Im SQL Standard sind zwei Arten von Intervallen. interval day to second und interval year to month. Beide haben verschiedene Genauigkeiten. In "year to month" kann keine Stunden oder Minute verarbeiten. Ein "day to second" dafür keine Monate oder Jahre.

Welches Ergebnis eine Subtraktion hat, hängt von den Datentype der beiden Parametern ab. Ähnlich wie bei Zahlen. integer - integer liefert integer, decimal - decimal liefert decimal usw. Oracle und DB2 sind da ziemlich pingelig was das angeht. Postgres kennt zwar die Bezeichnungen (Datentypen) auch, kann aber letztendlich jede "Art" von Interval darstellen also auch ein Interval welches Jahre, Monate, Tage, Minuten und Sekunden enthalten kann.

Microsofts datediff liefert kein Ergebnis vom Typ interval (den Typ kennt SQL Server gar nicht), sondern immer einen Integer Wert. Weil man einem Integer aber nicht ansieht welche Einheit (Tage, Stunden, Minuten) er repräsentiert, muss man die Einheit beim Aufruf der Funktion mitgeben. Ähnliches gilt auch für MySQL/MariaDB. Aber anstatt einen Fehler zu werfen wenn ein von den Datentypen nicht unterstützter Operator verwendet wird, wird halt alles "irgendwie" zu einer Zahl umgewandelt und dann subtrahiert. Welchen Sinn das haben soll erschließt sich mir nicht.
 
Also, die Berechnung von MySQL ist völlig OK !! wenn man sich ansieht wie eine Datum intern gespeichert wird.

Wenn du dies einmal ausführt

Code:
SELECT
    *,
    Enddatum+0,
    Startdatum+0,
    DATEDIFF(Enddatum, Startdatum) AS "Prüfspalte"
FROM tblDatumsangaben;


Bildschirmfoto 2022-05-12 um 11.04.17.png

Hier kann man sehen das die einzelnen Werte TTTMMDD jeweils dezimal abgelegt werden und somit
bei einer Subtraktion der korrekte, aber nicht zu brauchende, Wert herauskommt.

Ausserdem, was sollte denn rauskommen ? Datum - Datum = Daatum ? Demnach wäre es ja
das Jahr 0 und der Monat 0 und das wäre auch falsch. Und warum sollten Tage und nicht Stunden oder Wochen als Ergebnis kommen. Also man muss schon die vorgesehenen Funktionen nehmen.
 
Werbung:
Zurück
Oben