Jörg: mysql BETWEEN

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

akzeptierte Antworten

  1. 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

    --
    sumpsi - posui - obstruxi
    1. 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

      --
      200 ist das neue 35.
      1. 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

        1. 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

          --
          200 ist das neue 35.
          1. 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

          2. 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

            1. 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

              --
              200 ist das neue 35.
              1. Hallo,

                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).

                Einfach +1 ?
                Nicht + 1 day?

                Jörg

                1. Hallo

                  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).

                  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

                  --
                  200 ist das neue 35.

                  1. PostgreSQL hat soetwas nicht, kann aber natürlich auch an Zeitwerten herumrechnen: PostgreSQL DATEADD() Equivalent ↩︎

                  1. 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

                    --
                    sumpsi - posui - obstruxi