mysql BETWEEN
Jörg
- mysql
1 Rolf B
Hallo,
ich bin davon ausgegangen, dass mysql-BETWEEN folgendes bedeutet:
BETWEEN '2022-06-01' AND '2022-06-30' ist dasselbe wie >= '2022-06-01' AND <= '2022-06-30'
Wenn ich damit falsch liege, dann ok.
Aber wenn nicht, warum werden mir dann Rechnungen bei nachfolgender Query nicht angezeigt, die am 30.06.2022 erstellt wurden?
SELECT ID FROM rg WHERE Erstelldatum BETWEEN '2022-06-01' AND '2022-06-30'
Meine Spalte Erstelldatum ist eine datetime-Spalte.
Und es sind am 30.06.2022 definitiv Rechnungen erstellt worden und sie stehen auch in der db drin. Und wenn ich die Query auf BETWEEN '2022-06-01' AND '2022-07-01' ändere, bekomme ich auch die Rechnungen mit Erstelldatum 30.06.2022 angezeigt.
Wo liegt hier der Fehler?
Jörg
Hallo Jörg,
was genau steht für die Spalte ErstellDatum in der DB? Hast Du Beispiele?
Warum frage ich: Ich mutmaße, dass da auch Uhrzeiten stehen. Und die Angabe '2022-06-30' bedeutet: Mitternacht vom 29. auf den 30. Juni
Rolf
Hallo
Warum frage ich: Ich mutmaße, dass da auch Uhrzeiten stehen. Und die Angabe '2022-06-30' bedeutet: Mitternacht vom 29. auf den 30. Juni
Wenn MySQL das nicht anders macht als beispielsweise MS SQL, dann heißt …
BETWEEN '2022-06-01' AND '2022-06-30'
… wie du schon vermutest …
BETWEEN '2022-06-01 00:00:00' AND '2022-06-30 00:00:00'
… womit alle Rechnungen, die am 30.06.2022 nach 0 Uhr erstellt wurden – was mutmaßlich auf alle Rechnungen des Tages zutreffen wird –, nicht der Bedingung entsprechen.
Tschö, Auge
Hallo Rolf, hallo Auge,
na prima, dann haben wir ja den Fehler gefunden. Denn Ihr habt beide recht, dass in meiner Spalte auch Uhrzeiten drin stehen, womit dann (praktisch gesehen) alle vom 30.6 rausfallen.
Nächste Frage: Wie behebe ich den Fehler am einfachsten? Klar, ich könnte BETWEEN durch >= und <= ersetzen.
Geht es auch besser?
$d = new DateTime("$Year-$month");
$lastday = $d->format('Y-m-t');
$firstday = $d->format('Y-m-d');
$query= "SELECT
ID,
rg
WHERE Erstelldatum BETWEEN '".$firstday."' AND '".$lastday."'";
Gruß, Jörg
Hallo
na prima, dann haben wir ja den Fehler gefunden. Denn Ihr habt beide recht, dass in meiner Spalte auch Uhrzeiten drin stehen, womit dann (praktisch gesehen) alle vom 30.6 rausfallen.
Nächste Frage: Wie behebe ich den Fehler am einfachsten? Klar, ich könnte BETWEEN durch >= und <= ersetzen.
Ja, könntest du.
Geht es auch besser?
Natürlich. Es spricht nichts dagegen, Zeitstempel in BETWEEN
mitsamt einer Uhrzeit zu benutzen.
$d = new DateTime("$Year-$month"); $lastday = $d->format('Y-m-t'); $firstday = $d->format('Y-m-d'); $query= "SELECT ID, rg WHERE Erstelldatum BETWEEN '".$firstday."' AND '".$lastday."'";
Wenn du die aber weiterhin weglässt, wird das nichts.
$d = new DateTime("$Year-$month");
// Umsortiert, weil der erste Tag vor dem letzten kommt.
// Die Uhrzeit '00:00:00' ist optional, könnte aber wie bei $lastday angegeben werden
$firstday = $d->format('Y-m-d');
// Hier habe ich einfach eine passende Uhrzeit rangehängt
$lastday = $d->format('Y-m-t 23:59:59');
$query= "SELECT
ID,
rg
WHERE Erstelldatum BETWEEN '".$firstday."' AND '".$lastday."'";
Tschö, Auge
Hallo Auge,
Natürlich. Es spricht nichts dagegen, Zeitstempel in
BETWEEN
mitsamt einer Uhrzeit zu benutzen.
Ah ok. Genau sowas meinte ich, danke.
Jörg
Hallo,
Natürlich. Es spricht nichts dagegen, Zeitstempel in
BETWEEN
mitsamt einer Uhrzeit zu benutzen.
...
Wenn du die aber weiterhin weglässt, wird das nichts.
Was spricht dagegen, einfach einen Tag draufzuschlagen?
Gruß
Kalk
Hallo
Natürlich. Es spricht nichts dagegen, Zeitstempel in
BETWEEN
mitsamt einer Uhrzeit zu benutzen....
Wenn du die aber weiterhin weglässt, wird das nichts.
Was spricht dagegen, einfach einen Tag draufzuschlagen?
Praktisch wohl nichts. Es ist überaus unwahrscheinlich, dass beispielsweise zwischen 2022-06-30 23:59:59
und 2022-07-01 00:00:00
eine Rechnung erstellt wird. Falls das Datum aus einer manuellen Eingabe stammen sollte, erspart man sich mit dem anhängen der Uhrzeit einfach, das Datum umzuformen (2022-06-irgendwas
=> 2022-06-irgendwas + 1
).
Tschö, Auge
Hallo,
Was spricht dagegen, einfach einen Tag draufzuschlagen?
Praktisch wohl nichts. Es ist überaus unwahrscheinlich, dass beispielsweise zwischen
2022-06-30 23:59:59
und2022-07-01 00:00:00
eine Rechnung erstellt wird. Falls das Datum aus einer manuellen Eingabe stammen sollte, erspart man sich mit dem anhängen der Uhrzeit einfach, das Datum umzuformen (2022-06-irgendwas
=>2022-06-irgendwas + 1
).
Einfach +1 ?
Nicht + 1 day?
Jörg
Hallo
Was spricht dagegen, einfach einen Tag draufzuschlagen?
Praktisch wohl nichts. Es ist überaus unwahrscheinlich, dass beispielsweise zwischen
2022-06-30 23:59:59
und2022-07-01 00:00:00
eine Rechnung erstellt wird. Falls das Datum aus einer manuellen Eingabe stammen sollte, erspart man sich mit dem anhängen der Uhrzeit einfach, das Datum umzuformen (2022-06-irgendwas
=>2022-06-irgendwas + 1
).Einfach +1 ?
Nicht + 1 day?
Das ist kein Code, nur Pseudocode, um mein Anliegen zu verdeutlichen.
Wenn du in MySQL mit DATE_ADD
arbeiten willst, brauchst du natürlich die passende Syntax. Und ja, da ist INTERVAL 1 DAY
angesagt. Oder auch INTERVAL -1 DAY
, falls du einen Tag abziehen willst, wobei MySQL dafür auch die Funktion DATE_SUB
anbietet, bei der das negative Vorzeichen wegfällt. Andere SQL-Server, wie der von Microsoft, kennen nur DATEADD
oder auch DATE_ADD
oder DATE
[1]. Dort musst du bei Bedarf mit dem Vorzeichen hantieren, bei MySQL kannst du es oder eben auch nicht.
Tschö, Auge
PostgreSQL hat soetwas nicht, kann aber natürlich auch an Zeitwerten herumrechnen: PostgreSQL DATEADD() Equivalent ↩︎
Hallo Auge,
die portablere Lösung ist vermutlich, das Intervallende in PHP zu bestimmen.
<?php
$reportMonth = new DateTimeImmutable("2022-08");
$firstday = $reportMonth->format('Y-m-d');
$lastday = $reportMonth->add(new DateInterval("P1M"))->format('Y-m-d');
echo "first: $firstday, last: $lastday, ";
Ich bevorzuge für so was die DateTimeImmutable
-Klasse, weil DateTime::add
das Objekt modifiziert statt ein neues zu erzeugen.
Rolf