MySQL Altersabfragen aus Geburtsdaten, stehe voll auf dem Schlauch

Gast #4163781
Lesenswert?
• ▲
▼
Hallo alle miteinander,

Ich möchte für eine Statistik verschiedene Altersbereiche der Benutzer 
meiner Anwendung auswerten (also so etwas wie "Jungen, 13-17 Jahre" usw.

Mein bisheriger Code schaut so aus (Abfrage aus PHP):
1
           
2
AND User.Geburtstag BETWEEN DATE_SUB(NOW(),INTERVAL ".$To." YEAR) 
3
AND DATE_SUB(NOW(),INTERVAL ".$From." YEAR)

Dabei wäre jetzt $From eben die 13 und $To die 17.
Ich habe mittlerweile festgestellt, dass da was nicht sitmmt, weil so 
einige Leute durch das "Raster" fallen und nirgens auftauchen, bin 
jedoch zu noch keiner funktionierenden Lösung gekommen.

Ich hatte schon die Idee, dass man ja 1 Jahr lang sein Alter hat und 363 
Tage addiert bzw abgezogen, aber das war auch nicht richtig (oder ich 
hatte einen Fehler in meiner Query.

Ich weiss dass es eigentlich Pipieinfach sein müsste, aber ich stehe 
gerade so dermassen auf dem Schlauch und drehe mich im Kreis, dass es 
mein Hirn total blockiert.

Würde mich über ein wenig Input freuen, damit ich das Modul dieses WE 
noch fertig stellen kann.

Hoffe es findet sich jemand der mir hilft.

Vielen Dank!
Gast #4164547
Lesenswert?
• ▲
▼
Ok, was hier natürlich in meinem Codeschnipsel nicht ersichtlich ist:

Bei mir gehen nur Daten in die Query, die vorher mit 
mysqli_real_escap_string oder intval() "gecheckt" wurden. Trotzdem 
schlecht?
#4164574
Lesenswert?
• ▲
▼
Wenn das jetzt nich für Tage genau gelten sollte sondern nur für das 
Ganze Jahr.. so das die statistik wenn morgen jemand Geburtstag hätte 
nicht wieder anders aussieht.

Könnte fixer als Between sein.

Ungeprüft:
 WHERE YEAR(GEBURTSTAG) < YEAR(CURDATE())-ALTERMIN AND YEAR(GEBURTSTAG) 
>YEAR(CURDATE())-ALTERMAX
#4164582
Lesenswert?
• ▲
▼
Jens Plappert schrieb:
> Bei mir gehen nur Daten in die Query, die vorher mit
> mysqli_real_escap_string oder intval() "gecheckt" wurden. Trotzdem
> schlecht?

wenn ich mich richtig erinnere, gab es auch mit den Escape-Methoden 
mögliche Injections.

Nimm einfach Prepared statements, damit bist du garantiert auf der 
sicheren Seite und das Statement muss bei mehreren gleichartigen 
Abfragen (z.B. mehrere Altersgruppen) nur einmal kompiliert werden.
#4164651
Lesenswert?
• ▲
▼
Mich hat das weil es pratisch ist nicht in ruhe gelassen und habe mir 
das nochmal angeschaut,als Anhang mal eine Idee für einen automatischen 
3 Jahres Interval auf die ganze Tabelle ohne WHERE automatisch sortiert.

Bedarf noch einer Ergebnisprüfung, sieht schonmal gut aus.

SELECT COUNT(*) AS ANZAHL ,(YEAR(NOW())-YEAR(MIN(user_birthdate)))AS 
ALTERjahr,YEAR(MIN(user_birthdate))AS VON,YEAR(MAX(user_birthdate))AS 
BIS, ROUND(YEAR(user_BIRTHDATE)/3) AS jahresindex FROM `users` GROUP By 
jahresindex
Angehängte Dateien:
Gast #4177096
Lesenswert?
• ▲
▼
Die Variante mit dem 'TIMESTAMPDIFF' führt leider zu einem 'full table 
scan'. Bei 100 Eintägen mag das noch kein Problem sein, wenn es mal mehr 
werden schon.

Hab grad kein MySQL zum testen da, aber die Ursprungsvariante könnte an 
einem falschen Datentyp scheitern. Eventuell reicht es NOW() jeweils 
durch CURDATE() zu ersetzen. Ansonsten um den Aufruf von DATE_SUB() noch 
ein CAST() auf den für das Feld User.Geburtstag verwendeten Datentyp.
Gast #4181503
Lesenswert?
• ▲
▼
Hallo Jens,

Jens Plappert schrieb:
> Ich möchte für eine Statistik verschiedene Altersbereiche der Benutzer
> meiner Anwendung auswerten (also so etwas wie "Jungen, 13-17 Jahre" usw.
>
> Mein bisheriger Code schaut so aus (Abfrage aus PHP):
>
>
1
> AND User.Geburtstag BETWEEN DATE_SUB(NOW(),INTERVAL ".$To." YEAR)
2
> AND DATE_SUB(NOW(),INTERVAL ".$From." YEAR)
3
>
>
> Dabei wäre jetzt $From eben die 13 und $To die 17.
> Ich habe mittlerweile festgestellt, dass da was nicht sitmmt, weil so
> einige Leute durch das "Raster" fallen und nirgens auftauchen, bin
> jedoch zu noch keiner funktionierenden Lösung gekommen.

Möglicherweise ist es bei MySQL nicht so, aber bei anderen DBMS muß der 
erste Parameter für BETWEEN unbedingt vor dem zweiten liegen.

HTH,
Karl

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.