Robert123: SQL-Abfrage zur Klassifizierung nach Datum

Hallo,

habe ein Problem mit einer Abfrage, für die ich leider keine Lösung finde (jedoch aus der Vergangenheit weiß, dass dies irgendwie möglich sein müsste).

Ich habe eine Tabelle mit Namen und einem Datum dazu (als UNIX-Timestamp).

Weiters habe ich nun 3 oder 4 Daten von verschiedenen Tagen.

Nun will ich eine Select-Abfrage, die die Anzahl der Datensätze aus der Benutzertabelle ausgibt, welche:

  • vor dem ersten Datum liegen
  • zwischen dem ersten und dem 2. Datum liegen
  • ...
  • nach dem letzten Datum liegen.

Im Prinzip eine Klassenbildung.

Hat vl. jemand gerade ein passendes Beispiel bei der Hand?

Danke,
Robert.

  1. Ich habe eine Tabelle mit Namen und einem Datum dazu (als UNIX-Timestamp).

    Einen UNIX-Timestamp (time_t) oder einen UNIX-Timestamp (das was deine nicht näher genannte SQL-Datenbank darunter versteht).

    Hat vl. jemand gerade ein passendes Beispiel bei der Hand?

    Für welches DMBS? In den meisten Fällen wirst du vermutlicht mit DATEDIFF() und BETWEEN weiterkommen sofern du im DBMS deinen Timestamp in ein brauchbares Format konvertieren kannst. Genau das dürfte aber das Problem sein.

    1. Ich habe eine Tabelle mit Namen und einem Datum dazu (als UNIX-Timestamp).

      Einen UNIX-Timestamp (time_t) oder einen UNIX-Timestamp (das was deine nicht näher genannte SQL-Datenbank darunter versteht).

      Der Timestamp ist in einem integer-Feld gespeichert, also nur eine länger Zahl. Im übrigen sind beide Daten ein Unix-Timestamp (sowohl in der Tabelle, als auch die Grenzwerte).

      Hat vl. jemand gerade ein passendes Beispiel bei der Hand?

      Für welches DMBS? In den meisten Fällen wirst du vermutlicht mit DATEDIFF() und BETWEEN weiterkommen sofern du im DBMS deinen Timestamp in ein brauchbares Format konvertieren kannst. Genau das dürfte aber das Problem sein.

      MySQL

      1. Ich habe eine Tabelle mit Namen und einem Datum dazu (als UNIX-Timestamp).

        Einen UNIX-Timestamp (time_t) oder einen UNIX-Timestamp (das was deine nicht näher genannte SQL-Datenbank darunter versteht).

        Der Timestamp ist in einem integer-Feld gespeichert, also nur eine länger Zahl. Im übrigen sind beide Daten ein Unix-Timestamp (sowohl in der Tabelle, als auch die Grenzwerte).

        Ist dein Timestamp jetzt time_t oder ist er durch MySQL mittels UNIX_TIMESTAMP() erzeugt?

        Beide sind nicht kompatibel zueinander - ersterer ist vorzeichenbehaftet, letzterer nicht. Zudem gibt es stellenweise Abweichungen hinsichtlich Zeitzone, Schaltjahre/Schalttage/Schaltsekunden und Sommer/Winterzeit abweichen wenn man sie mit UNIX_TIMESTAMP() bzw. FROM_UNIXTIME() erzeugt (z.B. im Vegleich zu date/time in PHP).

        Hat vl. jemand gerade ein passendes Beispiel bei der Hand?

        Für welches DMBS? In den meisten Fällen wirst du vermutlicht mit DATEDIFF() und BETWEEN weiterkommen sofern du im DBMS deinen Timestamp in ein brauchbares Format konvertieren kannst. Genau das dürfte aber das Problem sein.

        DATEDIFF, FROM_UNIXTIME() und BETWEEN sollten ausreichen wenn du keine Zeitpunkte VOR dem 01.01.1970 vergleichen möchtest (Geburtstage z.B.) - aber mit etwas streuverlust (aus den oben genannten gründen) wenn eben die Zeitpunkte nicht von MySQL selbst kommen.

        1. Ich habe eine Tabelle mit Namen und einem Datum dazu (als UNIX-Timestamp).

          Einen UNIX-Timestamp (time_t) oder einen UNIX-Timestamp (das was deine nicht näher genannte SQL-Datenbank darunter versteht).

          Der Timestamp ist in einem integer-Feld gespeichert, also nur eine länger Zahl. Im übrigen sind beide Daten ein Unix-Timestamp (sowohl in der Tabelle, als auch die Grenzwerte).

          Ist dein Timestamp jetzt time_t oder ist er durch MySQL mittels UNIX_TIMESTAMP() erzeugt?

          Das weiß ich nicht. Habe die Timestamps per PHP (time()) erzeugt, und in die Datenbank übertragen. Jede Person hat einen, wenn sie sich anmeldet. In der Datenbank ist der Timestamp dann als Integer abgelegt.

          Glaube nicht, dass es mit BETWEEN und DATEDIFF funktioniert.

          Die Ausgabe soll in etwa so aussehen:

          Datumsklasse  |  Anzahl Benutzer
          --------------------------------
          Von x1-x2 | 4
          Von y1-y2 | 6
          Von z1-z2 | 2
          Nach z2 | 14

          1. Das weiß ich nicht. Habe die Timestamps per PHP (time()) erzeugt, und in die Datenbank übertragen. Jede Person hat einen, wenn sie sich anmeldet. In der Datenbank ist der Timestamp dann als Integer abgelegt.

            Dann ist es time_t und du bist mit den genannten Problemen konfrontiert.

            Glaube nicht, dass es mit BETWEEN und DATEDIFF funktioniert.

            Die Ausgabe soll in etwa so aussehen:

            Datumsklasse  |  Anzahl Benutzer

            Von x1-x2 | 4
            Von y1-y2 | 6
            Von z1-z2 | 2
            Nach z2 | 14

            Wenn du eine endliche Liste solcher bereiche hast, kannst du das problemlos mit mehreren einzelnen SELECT-Statements machen die du per union verbindest.

              SELECT  
                'Von x1-x2' as Datumsklasse  
                COUNT(benutzer) as `Anzahl Benutzer`  
              WHERE  
                datum BETWEEN datum1 AND datum2  
            UNION ALL  
              SELECT  
                -- weiter mit der nächsten Klasse
            

            datum1 und darum2 ermittelst du mit den Datums- und Zeitfunktionen von MySQL

            1. dachte es gibt für dieses problem einen eleganteren weg (eine einzige abfrage). werde ich es so machen,

              danke.

              1. dachte es gibt für dieses problem einen eleganteren weg (eine einzige abfrage). werde ich es so machen,

                Es ist eine einzelne Abfrage - nur weil da drinnen mehrmals SELECT steht sind es noch lange nicht mehrere Abfragen.

                Es gibt aber sicher noch elegantere Lösungen mit Gruppierungsfunktionen - aber dazu bin ich heute geistig nicht mehr in der Lage :)

              2. Hallo,

                dachte es gibt für dieses problem einen eleganteren weg (eine einzige abfrage).

                Wenn Du die Berechnung der "Klasse" entsprechend formulieren kannst, dann kannst Du die Abfrage vereinfachen. Wenn die Zeiträume jedoch beliebig vorgegebene Bereiche einnehmen können, dann kannst Du mit UNION arbeiten oder ein entsprechendes CASE-Konstrukt zusammenbauen. Wie willst Du es ohne Berechnungsvorschrift einfacher haben?

                SELECT  
                    klasse,  -- Liebes DBMS, Du musst schon erraten, wie ich's heute haben will.  
                    anzahl  
                FROM  
                    tabelle
                

                Freundliche Grüße

                Vinzenz