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

7 réponses

1 2
Avatar
Antoine Polatouche
a écrit :
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?



Parce que avec php tu peux faire le select qui retourne les
anniversaires dans l'ordre puis tu récupères les lignes tant que le
nombre de jours avant l'anniversaire est identique à la première ligne.
Avatar
mosaic93
On 27 juin, 23:21, Antoine Polatouche wrote:

Parce que avec php tu peux faire le select qui retourne les
anniversaires dans l'ordre puis tu récupères les lignes tant que le
nombre de jours avant l'anniversaire est identique à la première lign e.



Effectivement, ca va certainement se terminer par ca.

Un truc du genre?

$query=mysql_query($requete, $connect);

while($row=mysql_fetch_array($query)){

if(isset($tmp) AND $tmp!=$row['jour_avant_anniv']) break;

echo $row['nom'].'-'.$row['jour_avant_anniv'].' j<br />';

$tmp=$row['jour_avant_anniv'];
}


Par curiosité, j'aurai bien aimé savoir le faire en total sql mais ca
à l'air de compliquer inutilement les choses et surtout je ne trouve
pas la solution.

Merci pour l"idée.

--
mosaic
Avatar
Antoine Polatouche
a écrit :
On 27 juin, 23:21, Antoine Polatouche wrote:

Parce que avec php tu peux faire le select qui retourne les
anniversaires dans l'ordre puis tu récupères les lignes tant que le
nombre de jours avant l'anniversaire est identique à la première ligne.



Effectivement, ca va certainement se terminer par ca.

Un truc du genre?

$query=mysql_query($requete, $connect);

while($row=mysql_fetch_array($query)){

if(isset($tmp) AND $tmp!=$row['jour_avant_anniv']) break;

echo $row['nom'].'-'.$row['jour_avant_anniv'].' j<br />';

$tmp=$row['jour_avant_anniv'];
}



Oui.

Par curiosité, j'aurai bien aimé savoir le faire en total sql mais ca
à l'air de compliquer inutilement les choses et surtout je ne trouve
pas la solution.



Je ne crois pas qu'il y ait une façon simple de le faire.
On peut simplifier un peu la syntaxe en créant une stored function
AvantAnniv(), mais la requête restera lourde.

La logique serait plutôt de faire une requête pour les anniversaires du
jours, puis s'il n'y en a pas une requête avec ORDER BY et LIMIT n pour
limiter le nombre des prochains, ou d'avoir les prochains dans un délai
de n jours ?


Merci pour l"idée.



De rien.
La question est pertinente, je l'ai toujours zappée avec une boucle dans
le langage client ;-)
Si tu trouves une réponse un jour, ça m'intéresse.
Avatar
mosaic93
On 27 juin, 20:28, wrote:
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.




ARGH! Après un peu de repos sans SQL, je relie tout ca et m'apercois
que j'ai oublié le "FROM membres" dans le select du WHERE...

Et là, au miracle de la technologie, ca passe. C'est pas beau, mais ca
passe.

Je vais automatiser tout cela, afin qu'un mail me soit envoyé
quotidiennement 10 jours avant l'anniversaire de ma femme, ca
m'évitera des reproches aussi long que la requete... ;-)

Merci pour votre aide sur la syntaxe WHERE ... in (SELECT) que j'ai
découvert.

--
mosaic
Avatar
Fred Brouard - SQLpro
Antoine Polatouche a écrit :
[...]

Par curiosité, j'aurai bien aimé savoir le faire en total sql mais ca
à l'air de compliquer inutilement les choses et surtout je ne trouve
pas la solution.



Je ne crois pas qu'il y ait une façon simple de le faire.
On peut simplifier un peu la syntaxe en créant une stored function
AvantAnniv(), mais la requête restera lourde.



Si, j'ai posté cela dans mes puzzles SQL... à lire donc à :
http://sqlpro.developpez.com/SQL_AZ_P.html
Problème n° 5 - dates d'anniversaire

la solution est :


SELECT NO_CLI
FROM Client
WHERE
(( 36 < (EXTRACT(MONTH FROM DATE_NAISSANCE_CLI)-1)*31
+EXTRACT(DAY FROM DATE_NAISSANCE_CLI))
AND
((EXTRACT(MONTH FROM DATE_NAISSANCE_CLI)-1)*31
+EXTRACT(DAY FROM DATE_NAISSANCE_CLI)
<= 84 ))

Mais d'ou viennent les chiffres 35 et 84 me direz vous ?
Simple : 5 février => (2-1)*31 + 5 = 36 et 22 mars => (3-1)*31+22 = 84

Bien entendu vous pouvez rendre la requête SQL ci dessus parfaitement
paramétrable.
Partons d’une date d et d’un intervalle i. Recherchons tous les clients
dont les anniversaires vont être compris entre la date d et la date d +
i (ou i est un nombre de jours). Calculons MinDay et MaxDay de la façon
suivante
MinDay = (mois(d)-1)*31+jour(d)
MaxDay = MinDay + i + 1
Alors la requête s'écrit dorénavant :
SELECT NO_CLI
FROM Client
WHERE
(( :minDay <
(EXTRACT(MONTH FROM DATE_NAISSANCE_CLI)-1)*31
+EXTRACT(DAY FROM DATE_NAISSANCE_CLI))
AND
((EXTRACT(MONTH FROM DATE_NAISSANCE_CLI)-1)*31
+EXTRACT(DAY FROM DATE_NAISSANCE_CLI)
<= :MaxDay ))

De plus, si vous disposez d'un operateur comme CURRENT_DATE, avec un peu
d'astuce, vous pouvez trouver une requête vous permettant de trouver
tous les clients dont la date anniversaire sera dans les 15 jours qui
viennent... mais attention au effets de bord dans ce dernier cas !



La logique serait plutôt de faire une requête pour les anniversaires du
jours, puis s'il n'y en a pas une requête avec ORDER BY et LIMIT n pour
limiter le nombre des prochains, ou d'avoir les prochains dans un délai
de n jours ?


Merci pour l"idée.



De rien.
La question est pertinente, je l'ai toujours zappée avec une boucle dans
le langage client ;-)
Si tu trouves une réponse un jour, ça m'intéresse.





--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
********************* http://www.datasapiens.com ***********************
Avatar
Antoine Polatouche
Fred Brouard - SQLpro a écrit :
Antoine Polatouche a écrit :
[...]
Je ne crois pas qu'il y ait une façon simple de le faire.
On peut simplifier un peu la syntaxe en créant une stored function
AvantAnniv(), mais la requête restera lourde.



Si, j'ai posté cela dans mes puzzles SQL... à lire donc à :
http://sqlpro.developpez.com/SQL_AZ_P.html
Problème n° 5 - dates d'anniversaire

la solution est :


SELECT NO_CLI
FROM Client
WHERE
(( 36 < > (EXTRACT(MONTH FROM DATE_NAISSANCE_CLI)-1)*31
+EXTRACT(DAY FROM DATE_NAISSANCE_CLI))
AND
((EXTRACT(MONTH FROM DATE_NAISSANCE_CLI)-1)*31
+EXTRACT(DAY FROM DATE_NAISSANCE_CLI)
<= 84 ))



Je crois que ce n'est pas exactement la réponse à la question qui était
comment trouver les prochains anniversaires, sans préjuger de quand ils
se produiront: la prochaine date anniversaire avec tous les records
concernés par cette date...
Avatar
nobody
Antoine Polatouche a écrit :
Fred Brouard - SQLpro a écrit :
Antoine Polatouche a écrit :
[...]
Je ne crois pas qu'il y ait une façon simple de le faire.
On peut simplifier un peu la syntaxe en créant une stored function
AvantAnniv(), mais la requête restera lourde.


Si, j'ai posté cela dans mes puzzles SQL... à lire donc à :
http://sqlpro.developpez.com/SQL_AZ_P.html
Problème n° 5 - dates d'anniversaire

la solution est :


SELECT NO_CLI
FROM Client
WHERE
(( 36 < >> (EXTRACT(MONTH FROM DATE_NAISSANCE_CLI)-1)*31
+EXTRACT(DAY FROM DATE_NAISSANCE_CLI))
AND
((EXTRACT(MONTH FROM DATE_NAISSANCE_CLI)-1)*31
+EXTRACT(DAY FROM DATE_NAISSANCE_CLI)
<= 84 ))



Je crois que ce n'est pas exactement la réponse à la question qui était
comment trouver les prochains anniversaires, sans préjuger de quand ils
se produiront: la prochaine date anniversaire avec tous les records
concernés par cette date...





à mon avis cela sort les clients qui ont un anniversaire entre le 5
janvier et le 22 février

Sacré Fred toujours égale a lui même comme l'a dit trés justement un
certain Hélios "les SGBD c'est comme le Tennis c'est pas ceux qui
écrivent les livres ou donnent les cours qui sont les champions" :-)
1 2