Prochains anniversaires ?
Bonjour à tous,
Pour une application, j'ai besoin d'afficher par exemple les prochains anniversaires des 5 prochains clients.
Sachant que j'ai leur date de naissance au format date classique, je planche pas mal sur cette fonction.
Quelqu'un aurait une idée ?
Merci d'avance :)
Webmaster de Clikmag http://www.clikmag.fr
Comment sont stockées les dates ?
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Elles sont stockées en format DATE (sous Mysql : AAAA-MM-JJ).
Webmaster de Clikmag http://www.clikmag.fr
Il faut alors simplement faire une requête sur la table, en triant par date dans le sens descendant et limiter les résultats au nombre voulu.
Quelque chose dans ce goût là :
select * from contacts order by birthday desc limit 5 ;
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Malheureusement c'est pas aussi simple :(
Ca me retourne bien les prochaines dates, mais il prend en compte l'année ce qui fait que ceux nés en 1930 passent avant les autres ...
J'ai biensûr testé avec un DATE_FORMAT() mais idem, ça ne semble pas marcher :(
Webmaster de Clikmag http://www.clikmag.fr
Ah ben forcément, quel couillon je fais. J'ai pas pensé aux années.
Mais effectivement, c'est du coup plus compliqué. J'ai fait une petite requête, et ça fonctionne, sauf pour mon anniversaire. Et j'avoue ne pas en saisir la raison. Si quelqu'un a une idée ?
Ah, et comment gérer l'âge de ceux qui sont nés le 29 février ?
En ce qui concerne la solution que je te propose, je me base sur le jour de l'année pour déterminer si l'anniversaire concerne cette année ou l'année prochaine, et j'en déduis la date anniversaire.
create temporary table birthdays
( name varchar(100) not null
, birth date not null
) ;
insert into birthdays
values ('Mickael', '1980-12-22')
, ('Mathieu', '1955-09-06')
, ('Fabienne', '1962-01-03')
, ('Laetitia', '1981-12-28')
, ('Audrey', '1983-04-15')
;
select name
, if(dayofyear(birth) > dayofyear(now())
, makedate(year(now()), dayofyear(birth))
, makedate(year(now() + interval 1 year), dayofyear(birth))
)
as anniversary
, birth
from birthdays
order by anniversary asc
limit 5
;
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Ah ben en fait le bug est lié aux années bisextiles. Et ça, je sais as comment je vais le résoudre. Je vais y réfléchir (ou si quelqu'un a une idée pertinente).
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
En y réfléchissant, quelques concat feront l'affaire.
select name, birth
, date(
concat(
anniversary_year
, '-'
, month(birth)
, '-'
, if(day(birth) = 29 and month(birth) = 2
and dayofyear(concat(anniversary_year, '-12-31')) = 365
, 28, 29)
)
) as anniversary
, anniversary_year - year(birth) as age
from
(
select name
, if(dayofyear(birth) >= dayofyear(now())
, year(now())
, year(now() + interval 1 year)
) as anniversary_year
, birth
from birthdays
) as b
order by anniversary asc
limit 5
;
Par contre, ça risque d'être très inefficace sur une grosse table. Si ça pose problème, le mieux ce sera de faire un cron quotidien pour prémâcher le travail. ensuite, ce qui peut être marrant, c'est de jouer avec les fuseaux horaires, voir de considérer l'heure de naissance :D
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
le 08/05/2009 à 15:33
jeca
Bonjour,
S'il s'agit de lister les 5 prochains anniversaires, ceci devrait suffire :
select *
from taTable
where date_format(date_nais, '%m-%d') > date_format(curdate(), '%m-%d')
order by date_format(date_nais, '%m-%d') desc
limit 0, 5
cordialement
(jeca) Tu as quand même le bogue des années bissextiles.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.