Afficher uniquement les minimum d'un calcul

Le
mosaic93
Bonjour,

Sous Mysql 4.1, je cherche à afficher les enregistrements dont le
calcul sur un champ me renvoi un minimum.

Par exemple, pour illustrer mon problème, car ce n'est pas tout à fait
ce que je veux faire:

CREATE TABLE `calendrier` (
`nom` varchar(20) NOT NULL default '',
`evenement` date NOT NULL default '0000-00-00'
) TYPE=MyISAM;


INSERT INTO `calendrier` VALUES ('Dupont', '2007-11-26');
INSERT INTO `calendrier` VALUES ('Durand', '2007-07-14');
INSERT INTO `calendrier` VALUES ('Martin', '2008-10-05');
INSERT INTO `calendrier` VALUES ('Marc', '2007-07-14');


Je calcule le nombre de jours entre maintenant et la date de
l'événement:
SELECT nom, (TO_DAYS(evenement)) - TO_DAYS(CURDATE()) as prochain
FROM calendrier



Je souhaiterais récupérer:
Durand 18
Marc 18

C'est à dire toutes les enregistrements pour lesquels prochain est le
plus petit.

J'ai essayé d'utiliser MIN, mais je ne peux pas faire de GROUP BY sur
le champ prochain. J'ai tenté en lisant la doc, des HAVING, des
subselect, mais sans grand succès. Il faut dire que je ne suis pas un
spécialiste du domaine, c'est pourquoi je fais appel aux spécialistes.

Si quelqu'un pouvait me confirmer que ce que je souhaite faire est
possible, et éventuellement me donner une piste de recherche, je lui
en serais reconnaissant.

--
mosaic
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
ALain Montfranc
Le #21843481
a écrit
Bonjour,

Sous Mysql 4.1, je cherche à afficher les enregistrements dont le
calcul sur un champ me renvoi un minimum.

Par exemple, pour illustrer mon problème, car ce n'est pas tout à fait
ce que je veux faire:

CREATE TABLE `calendrier` (
`nom` varchar(20) NOT NULL default '',
`evenement` date NOT NULL default '0000-00-00'
) TYPE=MyISAM;


INSERT INTO `calendrier` VALUES ('Dupont', '2007-11-26');
INSERT INTO `calendrier` VALUES ('Durand', '2007-07-14');
INSERT INTO `calendrier` VALUES ('Martin', '2008-10-05');
INSERT INTO `calendrier` VALUES ('Marc', '2007-07-14');


Je calcule le nombre de jours entre maintenant et la date de
l'événement:
SELECT nom, (TO_DAYS(evenement)) - TO_DAYS(CURDATE()) as prochain
FROM calendrier



Je souhaiterais récupérer:
Durand 18
Marc 18

C'est à dire toutes les enregistrements pour lesquels prochain est le
plus petit.

J'ai essayé d'utiliser MIN, mais je ne peux pas faire de GROUP BY sur
le champ prochain. J'ai tenté en lisant la doc, des HAVING, des
subselect, mais sans grand succès. Il faut dire que je ne suis pas un
spécialiste du domaine, c'est pourquoi je fais appel aux spécialistes.

Si quelqu'un pouvait me confirmer que ce que je souhaite faire est
possible, et éventuellement me donner une piste de recherche, je lui
en serais reconnaissant.



un select min(TO_DAYS(evenement) - TO_DAYS(CURDATE()) renvoie la
distance

donc un :

select nom, TO_DAYS(evenement)) - TO_DAYS(CURDATE()) from
calendrier c,
(select min(TO_DAYS(evenement) - TO_DAYS(CURDATE()) as distance from
calendrier) m
where M;distance = (TO_DAYS(evenement)) - TO_DAYS(CURDATE())

devrait le faire, non ?

ou

select nom, TO_DAYS(evenement)) - TO_DAYS(CURDATE()) from
calendrier c
where
TO_DAYS(evenement)) - TO_DAYS(CURDATE()) in
(select min(TO_DAYS(evenement) - TO_DAYS(CURDATE()) from calendrier)
Antoine Polatouche
Le #21843471
a écrit :
Bonjour,

Sous Mysql 4.1, je cherche à afficher les enregistrements dont le
calcul sur un champ me renvoi un minimum.

Par exemple, pour illustrer mon problème, car ce n'est pas tout à fait
ce que je veux faire:

CREATE TABLE `calendrier` (
`nom` varchar(20) NOT NULL default '',
`evenement` date NOT NULL default '0000-00-00'
) TYPE=MyISAM;


INSERT INTO `calendrier` VALUES ('Dupont', '2007-11-26');
INSERT INTO `calendrier` VALUES ('Durand', '2007-07-14');
INSERT INTO `calendrier` VALUES ('Martin', '2008-10-05');
INSERT INTO `calendrier` VALUES ('Marc', '2007-07-14');


Je calcule le nombre de jours entre maintenant et la date de
l'événement:
SELECT nom, (TO_DAYS(evenement)) - TO_DAYS(CURDATE()) as prochain
FROM calendrier



Je souhaiterais récupérer:
Durand 18
Marc 18

C'est à dire toutes les enregistrements pour lesquels prochain est le
plus petit.



SELECT nom, (TO_DAYS(evenement)) - TO_DAYS(CURDATE()) as prochain
FROM calendrier WHERE evenement = (SELECT MIN(evenement) FROM calendrier)

devrait marcher...
mosaic93
Le #21852341
On 26 juin, 22:34, ALain Montfranc

un select min(TO_DAYS(evenement) - TO_DAYS(CURDATE()) renvoie la
distance

donc un :

select nom, TO_DAYS(evenement)) - TO_DAYS(CURDATE()) from
calendrier c,
(select min(TO_DAYS(evenement) - TO_DAYS(CURDATE()) as distance from
calendrier) m
where M;distance = (TO_DAYS(evenement)) - TO_DAYS(CURDATE())

devrait le faire, non ?




Celle-ci ne passe pas (meme en corrigeant le ; en . et les
parenthèses), mysql me sort une erreur "aucune base sélectionnée". A
mojns que j'ai laissé passé une erreur de synthaxe.


ou

select nom, TO_DAYS(evenement)) - TO_DAYS(CURDATE()) from
calendrier c
where
TO_DAYS(evenement)) - TO_DAYS(CURDATE()) in
(select min(TO_DAYS(evenement) - TO_DAYS(CURDATE()) from calendrier)



Super. Celle-ci est très bien (en repositionnant les parenthèse). Je
n'avais pas pensé (car jamais utilisé encore) au IN.

Merci beaucoup, je vais pouvoir aller dormir plus serein.

--
mosaic
mosaic93
Le #21852331
On 26 juin, 23:56, Antoine Polatouche

SELECT nom, (TO_DAYS(evenement)) - TO_DAYS(CURDATE()) as prochain
FROM calendrier WHERE evenement = (SELECT MIN(evenement) FROM calendrie r)

devrait marcher...




Effectivement, ca marche pour ce type d'exemple. C'est clair et
propre, je vais voir si ca passe dans mon problème plus général car,
dans ce dernier, je ne peux directement faire référence au champ
evenement, mais seulement a un calcul sur evenement. Or quand, deriere
la clause WHERE je fais référence à un champ calculé, mysql me
retourne une erreur.

Merci du temps passé et de la rapidité de réponse.

--
mosaic
Antoine Polatouche
Le #21852321
a écrit :
On 26 juin, 23:56, Antoine Polatouche
SELECT nom, (TO_DAYS(evenement)) - TO_DAYS(CURDATE()) as prochain
FROM calendrier WHERE evenement = (SELECT MIN(evenement) FROM calendrier)

devrait marcher...




Effectivement, ca marche pour ce type d'exemple. C'est clair et
propre, je vais voir si ca passe dans mon problème plus général car,
dans ce dernier, je ne peux directement faire référence au champ
evenement, mais seulement a un calcul sur evenement. Or quand, deriere
la clause WHERE je fais référence à un champ calculé, mysql me
retourne une erreur.



Je ne vois pas du tout pourquoi tu ne peux accéder directement à
evenement, mais si tu peux accéder à TO_DAYS(evenement) alors tu peux faire

SELECT nom, (TO_DAYS(evenement)) - TO_DAYS(CURDATE()) as prochain
FROM calendrier WHERE TO_DAYS(evenement) = (SELECT
MIN(TO_DAYS(evenement)) FROM calendrier)

qui est nettement moins élégant...

Merci du temps passé et de la rapidité de réponse.



De rien ;-)
Bruno Baguette
Le #21852311
a écrit :
Or quand, deriere
la clause WHERE je fais référence à un champ calculé, mysql me
retourne une erreur.



Pourriez-vous préciser le message d'erreur complet ? Ca facilite
généralement (et je dis bien généralement) les choses !

--
Bruno Baguette -
mosaic93
Le #21852301
On 27 juin, 13:26, Bruno Baguette

Pourriez-vous préciser le message d'erreur complet ? Ca facilite
généralement (et je dis bien généralement) les choses !




En fait, j'ai une erreur lorsque je fais référence à l'alias du champ
calculé dans le where, et non au calcul lui meme.

Par exemple:
SELECT nom, (TO_DAYS(evenement) - TO_DAYS(CURDATE())) as prochain FROM
calendrier WHERE prochain =(SELECT MIN(TO_DAYS(evenement) -
TO_DAYS(CURDATE())) FROM calendrier)

me donne une erreur: #1054 - Champ 'prochain' inconnu dans where
clause


Alors que:
SELECT nom, (TO_DAYS(evenement) - TO_DAYS(CURDATE())) as prochain FROM
calendrier WHERE (TO_DAYS(evenement) - TO_DAYS(CURDATE())) =(SELECT
MIN(TO_DAYS(evenement) - TO_DAYS(CURDATE())) FROM calendrier)

me retourne le bon résultat.

C'est certainement tout à fait normal qu'on ne puisse pas faire
référence à l'alias dans le WHERE, mais ca m'aurait arrangé vu la
longueur du calcul sur le champ evenement que j'ai a faire ;-)

--
mosaic
mosaic93
Le #21852291
On 27 juin, 02:05, Antoine Polatouche

Je ne vois pas du tout pourquoi tu ne peux accéder directement à
evenement, mais si tu peux accéder à TO_DAYS(evenement) alors tu peux faire




Alors pour expliquer un peu plus avant mon idée (peut etre saugrenue),
je souhaite à partir d'une table comprenant des noms et des dates de
naissances afficher les ages et les prochains anniversaires par
rapport à la date courante.



Soit:

CREATE TABLE `membres` (
`id` int(5) unsigned NOT NULL auto_increment,
`nom` varchar(50) NOT NULL default '',
`prenom` varchar(50) NOT NULL default '',
`date_naissance` date NOT NULL default '0000-00-00',
PRIMARY KEY (`id`)
)


J'ai donc récupéré la liste ordonnée de ces infos avec:

SELECT
id, nom, prenom,
(YEAR(CURRENT_DATE)-YEAR(date_naissance)) - (RIGHT(CURRENT_DATE,5) <
RIGHT(date_naissance,5)) AS age,
TO_DAYS(date_naissance+ INTERVAL (YEAR(CURDATE())- YEAR(date_naissance)
+ IF(DAYOFYEAR(CURDATE()) > DAYOFYEAR(date_naissance), 1, 0)) YEAR)-
TO_DAYS( CURDATE() ) AS jour_avant_anniv
FROM membres order by jour_avant_anniv


Comme je souhaite accéder aux prochains anniversaires (plusieurs
personnes peuvent etre nées le meme jour et donc sont potentiellement
dans la liste des prochains anniversaires), je veux récupérer tous les
minimums pour jour_avant_anniv.

Pour l'instant, grace à vos conseils, j'ai testé:

SELECT
id, nom, prenom,
(YEAR(CURRENT_DATE)-YEAR(date_naissance)) - (RIGHT(CURRENT_DATE,5) <
RIGHT(date_naissance,5)) AS age,
TO_DAYS(date_naissance+ INTERVAL (YEAR(CURDATE())- YEAR(date_naissance)
+ IF(DAYOFYEAR(CURDATE()) > DAYOFYEAR(date_naissance), 1, 0)) YEAR)-
TO_DAYS( CURDATE() ) AS jour_avant_anniv
FROM membres
WHERE (TO_DAYS(date_naissance+ INTERVAL (YEAR(CURDATE())-
YEAR(date_naissance)+ IF(DAYOFYEAR(CURDATE()) >
DAYOFYEAR(date_naissance), 1, 0)) YEAR)- TO_DAYS( CURDATE() ) )
in
(SELECT MIN(TO_DAYS(date_naissance+ INTERVAL (YEAR(CURDATE())-
YEAR(date_naissance)+ IF(DAYOFYEAR(CURDATE()) >
DAYOFYEAR(date_naissance), 1, 0)) YEAR)- TO_DAYS( CURDATE() ) ))
order by jour_avant_anniv

C'est apparemment correct syntaxiquement (et logiquement?) mais ca ne
me retourne pas de résultat.

Vous comprenez aussi peut etre pourquoi j'aurais souhaité utiliser un
alias dans la clause WHERE...

Je vais continuer à chercher, meme si bien sur, ce serait plus facile
en 2 requetes, ou avec un traitement dans un langage de programmation
derrière. D'ailleurs, je ne sais pas ce qu'il en serait des
performances.

--
mosaic
Antoine Polatouche
Le #21852281
a écrit :
On 27 juin, 02:05, Antoine Polatouche
Je ne vois pas du tout pourquoi tu ne peux accéder directement à
evenement, mais si tu peux accéder à TO_DAYS(evenement) alors tu peux faire




Alors pour expliquer un peu plus avant mon idée (peut etre saugrenue),
je souhaite à partir d'une table comprenant des noms et des dates de
naissances afficher les ages et les prochains anniversaires par
rapport à la date courante.



Soit:

CREATE TABLE `membres` (
`id` int(5) unsigned NOT NULL auto_increment,
`nom` varchar(50) NOT NULL default '',
`prenom` varchar(50) NOT NULL default '',
`date_naissance` date NOT NULL default '0000-00-00',
PRIMARY KEY (`id`)
)


J'ai donc récupéré la liste ordonnée de ces infos avec:

SELECT
id, nom, prenom,
(YEAR(CURRENT_DATE)-YEAR(date_naissance)) - (RIGHT(CURRENT_DATE,5) <
RIGHT(date_naissance,5)) AS age,
TO_DAYS(date_naissance+ INTERVAL (YEAR(CURDATE())- YEAR(date_naissance)
+ IF(DAYOFYEAR(CURDATE()) > DAYOFYEAR(date_naissance), 1, 0)) YEAR)-
TO_DAYS( CURDATE() ) AS jour_avant_anniv
FROM membres order by jour_avant_anniv



[snip]

Je vais continuer à chercher, meme si bien sur, ce serait plus facile
en 2 requetes, ou avec un traitement dans un langage de programmation
derrière. D'ailleurs, je ne sais pas ce qu'il en serait des
performances.



Et les données sont traitées comment ensuite ?
mosaic93
Le #21852271
On 27 juin, 22:47, Antoine Polatouche
> Je vais continuer à chercher, meme si bien sur, ce serait plus facile
> en 2 requetes, ou avec un traitement dans un langage de programmation
> derrière. D'ailleurs, je ne sais pas ce qu'il en serait des
> performances.

Et les données sont traitées comment ensuite ?



A priori, je partais sur l'idée d'une récupération via php pour un
affichage web.

Mais le modèle pourrait donner lieu a tout type de vue.

Pourquoi?

--
mosaic
Publicité
Poster une réponse
Anonyme