Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Afficher uniquement les minimum d'un calcul

17 réponses
Avatar
mosaic93
Bonjour,

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

Par exemple, pour illustrer mon probl=E8me, car ce n'est pas tout =E0 fait
ce que je veux faire:

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


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'=E9v=E9nement:
SELECT nom, (TO_DAYS(evenement)) - TO_DAYS(CURDATE()) as prochain
FROM calendrier



Je souhaiterais r=E9cup=E9rer:
Durand 18
Marc 18

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

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

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

--
mosaic

10 réponses

1 2
Avatar
ALain Montfranc
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)
Avatar
Antoine Polatouche
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...
Avatar
mosaic93
On 26 juin, 22:34, ALain Montfranc wrote:


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
Avatar
mosaic93
On 26 juin, 23:56, Antoine Polatouche wrote:


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
Avatar
Antoine Polatouche
a écrit :
On 26 juin, 23:56, Antoine Polatouche wrote:

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 ;-)
Avatar
Bruno Baguette
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 -
Avatar
mosaic93
On 27 juin, 13:26, Bruno Baguette wrote:


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
Avatar
mosaic93
On 27 juin, 02:05, Antoine Polatouche wrote:

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
Avatar
Antoine Polatouche
a écrit :
On 27 juin, 02:05, Antoine Polatouche wrote:
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 ?
Avatar
mosaic93
On 27 juin, 22:47, Antoine Polatouche wrote:

> 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
1 2