MySql Abfrage: Geburtstage der nächsten 7 Tage

Hallo,
ich habe eine MySql Tabelle mit Personen und ihrem Geburtstdatum und möchte auf der Homepage nun die Personen auflisten lassen, die in den nächsten 7 Tagen Geburtstag haben!
Ich habe bereits alles mit den Datumsfunktionen von MySql probiert (DATE_ADD, TO_DAYS…), aber nichts hilft mir weiter.
Grund: Die Geburtsdaten liegen als YYYY-MM-DD vor und da diese Personen verschiedene Geburtsjahre haben, kann man schlecht mit
CURDATE() vergleichen!
Gibt es sonst einen Weg über PHP? Ich weiß nicht mehr weiter…
mfg
Sebastian

hi,

Grund: Die Geburtsdaten liegen als YYYY-MM-DD vor und da diese

warum sortierst du dir die info nicht in ein (assoziatives) array.
anschliessend nur noch vergleichen.
du haust einen split ueber ‚-‘. das wird super ;o)

gruss josh

SELECT name, geburtstag FROM Personen
WHERE MONTH(geburtstag) = MONTH(DATE_ADD(NOW(), INTERVAL 7 DAYS));

Schau hier:
http://www.mysql.de/doc/de/Date_calculations.html

Chris von www.schlechte-doku-hasser.de

@XChris: Bereits ausprobiert! Geht leider nicht, da die Jahreszahlen nicht gleich sind!

@josh:
ich kann zwar ein etwas PHP aber damit kann ich jetzt nicht soooo viel anfangen! Kannst du mal ein Beispiel zeigen?

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

SELECT name, geburtstag FROM Personen
WHERE MONTH(geburtstag) = MONTH(DATE_ADD(NOW(), INTERVAL 7
DAYS));

Würde das nicht alle Leute zurückgeben deren Geburtstag in dem Monat den wir in sieben Tagen haben liegt?

Um wirklich im 7 Tage-Intervall zu bleiben könnte die Abfrage wie folgt aussehen:

SELECT name, geburtstag FROM Personen
 WHERE geburtstag \>= NOW() AND geburtstag 

Grüße, Robert

Doch nicht ganz
Sorry, so wie ich das geschrieben habe haut das mit den Jahreszahlen nicht hin.

Wenn du Tag und Monat getrennt vergleichst, dann sollte es gehen.

SELECT name, geburtstag FROM Personen
 WHERE 
 MONTH( geburtstag ) \>= MONTH( NOW() ) 
 AND MONTH( geburtstag ) = DAY( NOW() ) 
 AND DAY( geburtstag ) 
Grüße, Robert

Ich hab das mal so ausprobiert! Klingt eigentlich auch ganz logisch…
…aber es klappt nicht! Jetzt liest er gar keine Namen aus! Aber er zeigt nach meiner Korrektur zumindest keine Fehler:

$Query = "SELECT name,vorname,DATE_FORMAT(geburtstag,’%d.%m.’) as geburtstag FROM abi_stufe WHERE
MONTH( geburtstag ) >= MONTH( CURDATE() )
AND MONTH( geburtstag ) = DAYOFMONTH( CURDATE() )
AND DAYOFMONTH( geburtstag ) ");
echo("Ihre Abfrage $Query war nicht erfolgreich! ");
exit();
}

Ich hab das mal so ausprobiert! Klingt eigentlich auch ganz
logisch…
…aber es klappt nicht! Jetzt liest er gar keine Namen aus!
Aber er zeigt nach meiner Korrektur zumindest keine Fehler:

Vielleicht hängt das Datum ja immernoch zu sehr drin…
Kann man das nicht irgendwie ganz rausschneiden?
Oder ich lasse vorher ein UPDATE durch die Tabelle laufen, dass jedes Geburtsjahr auf 2004 korrigiert…!!!

Die Sache ist ein Hund, da ist immer noch ein Denkfehler drinnen, und zwar bei den Tagen. Wenn wir heute z. B. den 31 haben, dann haben wir in 7 Tagen den 7. und der 7. ist natürlich kleiner als der 31.

Mit einer komplizierteren WHERE-Klausel müsste das aber auch gehen. Ich verwende da jetzt nur noch Kurzformen, nicht mehr den MySQL-Syntax

 (
 monat( now ) = monat( now + 7 ) AND
 tag( now ) = tag( geburtstag ) 
 )
OR
 (
 monat( now ) + 1 = monat( now + 7 ) AND
 ( monat( geburtstag ) = monat( now ) OR monat( geburtstag ) = monat( now + 7 ) ) AND
 ( tag( geburtstag ) \>= tag( now ) OR tag( geburtstag ) 
Die beiden grossen Blöcke die durch ein OR getrennt sind handeln jetzt die beiden unterschiedlichen Fälle ab.

Im ersten Fall ist das Monat in 7 Tagen noch dasselbe. Dann wird einfach über die Tage geprüft.

Im zweiten Fall ist das Monat in 7 Tage schon das nächste Monat. Dann muss der Geburtstag entweder in diesem Monat oder im nächsten liegen und der Tag des Geburtstag muss entweder grösser als der aktuelle Tag oder kleiner als der Tag des Datums in 7 Tagen sein.

Probier das mal, hoffentlich funkt das jetzt. :smile:

Grüße, Robert

vielen Dank! Hab aber gestern einen Tipp bekommen:

$Query = "SELECT name,vorname,DATE_FORMAT(geburtstag,’%d.%m.’) as geburtstag FROM tabelle WHERE
(MONTH(geburtstag) = MONTH( CURDATE() ) OR
MONTH(geburtstag)=MONTH( CURDATE() +INTERVAL 7 DAY ) ) AND
(DAYOFMONTH(geburtstag)>=DAYOFMONTH( CURDATE() ) OR
DAYOFMONTH(geburtstag)

Bist du sicher, dass das so funktioniert?

Stell dir z. B. den Fall vor:

Heute: 28.03
In 7 Tagen: 04.04
Geburtstag: 03.03

Der erste Block der Abfrage (mit den Monaten) gibt TRUE, weil month( geb ) = month( now ). Der zweite Block der Abfrage gibt auch TRUE, weil day( geb )

Sorry, ich hab das auch nur aus der Hüfte geschossen und nen Stück aus der MySQL Doku kopiert. War also ungetestet - aber sollte ja auch nur das WIE könnte es gehen demonstrieren und den zweck scheint es ja erfüllt zu haben.

:wink:

Chris


www.schlechte-doku-hasser.de

@josh:
ich kann zwar ein etwas PHP aber damit kann ich jetzt nicht
soooo viel anfangen! Kannst du mal ein Beispiel zeigen?

http://de3.php.net/manual/de/function.split.php

prinzipiell ist php.net eine super seite um viel ueber php-funktionen zu erfahren. einfach mal schauen.

die funktion split nimmt einen string, wie z.B. deine datumseingabe sowie ein trennzeichen. in deinem fall also ‚-‘, und zerlegt den string in ein array. wobei dass trennzeichen aussortiert wird.
$datum=„2004-03-05“
@A=split(’-’, $datum);

dann ist in A die info folgendermassen gespeichert:
A[i]=„bla“ ist zu lesen als A an der Stelle i hat den inhalt bla
A[0]=„2004“
A[1]=„03“
A[2]=„05“

so, und jetzt hast du die moeglichkeit ohne ueber jahreszahlen zu stolpern, die monate zu ueberpruefen.

bei php net bin ich gerade noch ueber zwei nette funktionen gestolpert, die genau auf dein problem passen.

schau doch mal hier:
http://de3.php.net/manual/de/function.mktime.php
und hier:
http://de3.php.net/manual/de/function.date.php

allerdings musst du erst den split ueber deinen string jagen, anschliessend kannst du mit date ueber dem array arbeiten…

gruss und viel spass

  • josh -

Ist zwar schon eine Weile her, dass die Anfrage gestellt wurde, aber dies lässt sich durchaus auch mit mySQL lösen:

Das nächste relevante Geburts-Datum muss aus den einzelnen Elementen so zusammengesetzt werden, dass es mit dem aktuellen Datum verglichen werden kann (in Strings wandeln, und dann wieder zurück zu Date mit STR_TO_DATE). Dann mit between mit heute und heute + 7 Tage (DATE_ADD) vergleichen:

SELECT * FROM mitglieder where STR_TO_DATE(concat(if((1+dayofyear(GEBOREN)) < dayofyear(curdate()) , 1+year(curdate()), year(curdate())),’,’,month(GEBOREN),’,’,day(GEBOREN)), ‚%Y,%m,%d‘) between curdate() and DATE_ADD(curdate(), INTERVAL 7 DAY)

Die IF Bedingung vergleicht die laufenden Jahrestage und wählt ggf. das nächste Jahr, wenn der Geburtstag heuer schon verstrichen ist. (Wichtig beim Jahreswechsel Ende Dezember)

Grüße,
Roland.

nur 19 Jahre… aber was soll’s…

1 Like