Trouver le plus grand ecart entre 2 valeurs

Trouver le plus grand ecart entre 2 valeurs - SQL/NoSQL - Programmation

Marsh Posté le 17-11-2008 à 15:10:23    

Bonjour à tous,
 
Je suis plongé depuis un moment dans une requête vraiment complexe.
Au lieu de sortir l'id qui a le prix le plus élevé ou le plus bas, je voudrais trouver l'id qui a le plus grand écart entre ses différents prix:
 
ma table tarifs : id • prix • date
 
A chaque fois que le prix d'un produit change il est enregistré dans la table ci-dessus.
La difficulté c'est de sortir les id qui ont connu la plus grosse variation de prix (donc le plus grand écart entre le prix le plus haut et le prix le plus bas)
 
J'ai testé des choses de ce genre:
select id_prix from tarifs order by (select max(prix) from tarifs)-(select min(prix) from tarifs) ASC
 
ou encore
select id_prix,(select max(prix) from tarifs) as max_prix,(select min(prix) from tarifs) as min_prix from tarifs order by max_prix-min_prix ASC
 
Mais ca ne fonctionne pas...
Auriez vous une piste?
 
Un grand merci pour votre aide.
A+

Reply

Marsh Posté le 17-11-2008 à 15:10:23   

Reply

Marsh Posté le 17-11-2008 à 15:31:25    

SELECT MAX(prix) , MIN(prix) , id  
FROM tarifs  
GROUP BY id
ORDER BY MAX(prix) - MIN(prix) DESC  
LIMIT 1


---------------

Reply

Marsh Posté le 17-11-2008 à 16:42:08    

ca fonctionne, merci mais il y a un problème, l'option de trie semble ne pas fonctionne regardes le résultat (avec un calcul d'evolution (valeur_max-valeur_min)/valeur_min:
13 : -550.92% ((19.66--4.36)/-4.36)
 
56 : 15% ((28.75-25)/25)
 
24 : 31.51% ((25-19.01)/19.01)
 
95 : 15 ((28.75-25)/25)
 
3 : -287.29 ((17.98--9.6)/-9.6)
 
41 : 15 ((28.75-25)/25)
 
Une idée...merci encore


Message édité par fredax le 17-11-2008 à 18:35:49
Reply

Marsh Posté le 18-11-2008 à 09:48:32    

pourquoi tu divises ?


---------------
What if I were smiling and running into your arms? Would you see then what I see now?  
Reply

Marsh Posté le 18-11-2008 à 09:50:39    

pour avoir un pourcentage de variation
tu as modifié le calcul d'evolution dans le ORDER BY ?


---------------

Reply

Marsh Posté le 18-11-2008 à 10:18:48    

flo850 a écrit :

SELECT MAX(prix) , MIN(prix) , id  
FROM tarifs  
GROUP BY id
ORDER BY MAX(prix) - MIN(prix) DESC  
LIMIT 1


 
select (max(prix) - min(prix)) as ecart ça marche pas?[:autobot]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 18-11-2008 à 10:47:37    

merci flo850 pour vos aide.
Vos propositions fonctionne mais je ne peux pas y intégrer un paramètre de date.
Le but final est de faire le tri des produits dont le prix à le plus augmenté sur une période de temps.
quelque chose comme:
 
SELECT MAX(prix) AS max_prix , MIN(prix) AS min_prix, id,date  
FROM tarifs  
WHERE date=\"$date_debut\" AND date=\"$date_fin\"  
GROUP BY id  
ORDER BY (MAX(prix) - MIN(prix))/MIN(prix) DESC, date ASC  
LIMIT 3
 
Ca me fait un bon trie des prix des plus grands écarts mais pas des plus grands écarts entre date_debut et date_fin.
Donc un truc du style : (max(prix) where date=date_debut) - (min(prix) where date=date_fin)
certainement une imbrication, mais je n'y arrive pas. :pt1cable:  
 
Encore une fois merci beaucoup pour votre aide.

Message cité 2 fois
Message édité par fredax le 18-11-2008 à 11:06:40
Reply

Marsh Posté le 18-11-2008 à 10:55:24    

Ca doit être sympa quand la valeur min est à zéro :D

Reply

Marsh Posté le 18-11-2008 à 10:56:52    

gzii a écrit :

Ca doit être sympa quand la valeur min est à zéro :D


c'est rare que tu vendes un truc zéro.[:dawa]


Message édité par skeye le 18-11-2008 à 10:57:11

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 18-11-2008 à 11:01:23    

Il y a des prix négatifs dans ce qu'il montre, ça ne m'étonnerait pas.

Reply

Marsh Posté le 18-11-2008 à 11:01:23   

Reply

Marsh Posté le 18-11-2008 à 11:02:01    

Et tu peux certifier que jamais, absolument jamais la BDD ne contiendra de valeur 0 dans cette colonne ? Jamais ?


Message édité par kao98 le 18-11-2008 à 11:02:28

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 18-11-2008 à 11:09:20    

non il n'y aura jamais jamais de 0 dans cette colonne.
 
(je viens d'éditer mon message au dessus, ma difficulté est d'ajouter à la solution de flo850 un paramètre de date)

Reply

Marsh Posté le 18-11-2008 à 11:29:47    

fredax a écrit :

merci flo850 pour vos aide.
Vos propositions fonctionne mais je ne peux pas y intégrer un paramètre de date.
Le but final est de faire le tri des produits dont le prix à le plus augmenté sur une période de temps.
quelque chose comme:
 
SELECT MAX(prix) AS max_prix , MIN(prix) AS min_prix, id,date  
FROM tarifs  
WHERE date=\"$date_debut\" AND date=\"$date_fin\"  
GROUP BY id  
ORDER BY (MAX(prix) - MIN(prix))/MIN(prix) DESC, date ASC  
LIMIT 3
 
Ca me fait un bon trie des prix des plus grands écarts mais pas des plus grands écarts entre date_debut et date_fin.
Donc un truc du style : (max(prix) where date=date_debut) - (min(prix) where date=date_fin)
certainement une imbrication, mais je n'y arrive pas. :pt1cable:  
 
Encore une fois merci beaucoup pour votre aide.


WHERE date > '$dateDebut' and date < '$dateFin'  
ou  
WHERE date BETWEEN '$dateDebut' AND '$datefin'


---------------

Reply

Marsh Posté le 18-11-2008 à 11:31:08    

fredax a écrit :

merci flo850 pour vos aide.
Vos propositions fonctionne mais je ne peux pas y intégrer un paramètre de date.
Le but final est de faire le tri des produits dont le prix à le plus augmenté sur une période de temps.
quelque chose comme:

 

SELECT MAX(prix) AS max_prix , MIN(prix) AS min_prix, id,date  
FROM tarifs
WHERE date=\"$date_debut\" AND date=\"$date_fin\"
GROUP BY id
ORDER BY (MAX(prix) - MIN(prix))/MIN(prix) DESC, date ASC  
LIMIT 3

 

Ca me fait un bon trie des prix des plus grands écarts mais pas des plus grands écarts entre date_debut et date_fin.
Donc un truc du style : (max(prix) where date=date_debut) - (min(prix) where date=date_fin)
certainement une imbrication, mais je n'y arrive pas. :pt1cable:

 

Encore une fois merci beaucoup pour votre aide.

 

ça devient tordu ton histoire...allez, une solution à la con (pas testée, hein, j'écris ça en live.[:dawa]) :

 
Code :
  1. SELECT id, sum(monjoliprix)
  2. FROM
  3. ( SELECT id, max(prix) AS monjoliprix
  4.  FROM tarifs
  5.  GROUP BY id
  6.  HAVING date=date_debut
  7. union
  8.  SELECT id, -min(prix) AS monjoliprix
  9.  FROM tarifs
  10.  GROUP BY id
  11.  HAVING date=date_fin
  12. )
  13. GROUP BY id



Message édité par skeye le 18-11-2008 à 11:34:27

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 18-11-2008 à 11:32:43    

fredax a écrit :

non il n'y aura jamais jamais de 0 dans cette colonne.


Ouais mais non. C'est pas comme ça qu'il faut raisonner.
Il faut se dire que la base peut contenir 0 et donc gérer ce cas particulier plutôt que de faire l'autruche en se disant "jamais il n'y aura de 0".
Une erreur de saisie, une RAZ par erreur, un produit offert (et donc prix=0) à un moment donné (promo particulière, offert avec un autre achat, que sais-je), une fausse manip du DBA, ...

Message cité 1 fois
Message édité par kao98 le 18-11-2008 à 11:33:03

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 18-11-2008 à 12:47:46    

Merci Skeye pour ta proposition, ca semble donner de bons résultats.
Mais comme tu peux le voir dessous il y a des incohérences dans le classement.
 
La requete:
SELECT id, sum(monjoliprix) FROM ( SELECT prix,date,id, max(prix) AS monjoliprix  FROM tarifs GROUP BY id HAVING date>=$date_debut
union
SELECT prix,date,id,-min(prix) AS monjoliprix  FROM tarifs GROUP BY id  HAVING date<=$date_fin) T GROUP BY id order by monjoliprix ASC
 
Résultat:
prix initial  prix final   evolution
19,00   18,50   -2,63%
19,00  18,50  -2,63%
20,02  19,00  -5,09%
20,27  20,80  +2,61%
20,01  19,51  -2,50%
26,50  25,25  -4,72%
 
Merci pour vos aides, je pense que je vais finir par y arriver

Reply

Marsh Posté le 18-11-2008 à 13:21:12    

order by sum(monjoliprix), non? puis je vois pas comment tu obtiens ce résultat avec cette requête.[:pingouino]


Message édité par skeye le 18-11-2008 à 13:21:53

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 18-11-2008 à 13:33:17    

flo850 a écrit :

pour avoir un pourcentage de variation
tu as modifié le calcul d'evolution dans le ORDER BY ?


j'avais compris, mais ça n'est pas la bonne formule pour le faire !


---------------
What if I were smiling and running into your arms? Would you see then what I see now?  
Reply

Marsh Posté le 18-11-2008 à 13:46:57    

jagstage je crois bien que pour le calcul d'un taux d'évolution ce soit (vf-vi)/vi
 
Skeye, j'ai essayé avec sum(monjoliprix) et ca donne le meme type de classement.
J'obtiens ce résultat parce qu'avec ma premiere requete, je déclenche une boucle qui va cherche les données qui me permettent de faire mon calcul.

Reply

Marsh Posté le 18-11-2008 à 13:48:13    

fredax a écrit :

jagstage je crois bien que pour le calcul d'un taux d'évolution ce soit (vf-vi)/vi
 
Skeye, j'ai essayé avec sum(monjoliprix) et ca donne le meme type de classement.
J'obtiens ce résultat parce qu'avec ma premiere requete, je déclenche une boucle qui va cherche les données qui me permettent de faire mon calcul.


oui mais alors si tu nous donnes pas toutes les infos on va pas faire de miracle. Montre ton vrai code.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 18-11-2008 à 13:55:07    

fredax a écrit :

jagstage je crois bien que pour le calcul d'un taux d'évolution ce soit (vf-vi)/vi


ça n'est pas une évolution de prix (ancien - nouveau prix), mais bien deux prix différents. On ne peut dès lors pas dire quel est la référence (le min ou le max ?)
 
Pour moi la seule chose que tu puisse dire c'est pmax/pmin pour exprimer la différence de prix
 
a+


---------------
What if I were smiling and running into your arms? Would you see then what I see now?  
Reply

Marsh Posté le 18-11-2008 à 13:55:32    

voici mon code :
 
$prelem=mysql_db_query($sql_bdd,"SELECT id, sum(monjoliprix) FROM ( SELECT prix,date,id, max(prix) AS monjoliprix  FROM tarifs GROUP BY id HAVING date>=$date_debut
union
SELECT prix,date,id,-min(prix) AS monjoliprix  FROM tarifs GROUP BY id  HAVING date<=$date_fin) T GROUP BY id order by sum(monjoliprix) ASC limit 6",$id_connex) or die(mysql_error());  
 
while($tab=mysql_fetch_array($prelem))
{
 
 $prelem3=mysql_db_query($sql_bdd,"select prix,date from tarifs where id=\"$tab[id]\" and date>=\"$date_debut\" order by date ASC,heure ASC limit 1",$id_connex) or die(mysql_error());
 $prix_debut=mysql_result($prelem3,0,"prix" );
 
 
 
 $prelem4=mysql_db_query($sql_bdd,"select prix,date from tarifs where id=\"$tab[id]\" and date<=\"$date_fin\" order by date DESC,heure DESC limit 1",$id_connex) or die(mysql_error());
 $prix_fin=mysql_result($prelem4,0,"prix" );
 
     
 $evolution=round((($prix_fin-$prix_debut)/$prix_debut)*100,2);
 
 
 echo"id : $prix_debut  $prix_fin $evolution";
}

Reply

Marsh Posté le 18-11-2008 à 14:04:14    

1) pourquoi mysql_db_query plutôt que mysql_query?
2) elles sont censées faire quoi tes requêtes là dans la boucle? Tu veux pas resélectionner le min() et le max() dans ta requête plutôt?[:pingouino]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 18-11-2008 à 14:06:42    

...au cas où tu comprendrais pas ce que j'ai dit, ça veut dire ça :
 
SELECT id, sum(monjoliprix), max(monjoliprix), -min(monjoliprix) ...


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 18-11-2008 à 14:07:23    

...et en fait c'est crétin, dans ce cas autant récupérer directement l'union et faire le traitement en php, bordel.:o


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 18-11-2008 à 14:23:09    

1) j'utilise mysql_db_query parceque je me connecte avec  
$id_connex = mysql_connect ("$sql_serveur","$sql_user","$sql_passwd" )or die ("connexion impossible" );
mysql_select_db("$sql_bdd",$id_connex);
 
alors peut etre que je me trompe mais ca fonctionne pas avec mysql_query.
 
2)ce que je recherche exactement c'est de sortir l'ecart entre valeur initiale (date_debut) et valeur finale (date_fin) et de trier les ecarts trouvés par ordre croissant
 
Je m'y prends peut etre mal mais comme tu l'as surement compris je suis pas vraiment un pro... donc je te remercie vraiment pour ton aide.

Reply

Marsh Posté le 18-11-2008 à 14:54:58    

fredax a écrit :

1) j'utilise mysql_db_query parceque je me connecte avec
$id_connex = mysql_connect ("$sql_serveur","$sql_user","$sql_passwd" )or die ("connexion impossible" );
mysql_select_db("$sql_bdd",$id_connex);

 

alors peut etre que je me trompe mais ca fonctionne pas avec mysql_query.

 

ça devrait. Enfin bref, c'est pas le plus important.

 
fredax a écrit :

2)ce que je recherche exactement c'est de sortir l'ecart entre valeur initiale (date_debut) et valeur finale (date_fin) et de trier les ecarts trouvés par ordre croissant
Je m'y prends peut etre mal mais comme tu l'as surement compris je suis pas vraiment un pro... donc je te remercie vraiment pour ton aide.

 

tu as toutes les infos qu'il te faut avec la première requête, il suffit de les remonter dans le select! et tu tries à l'envers (desc, pas asc!), ce qui peut expliquer tes soucis de tri :D


Message édité par skeye le 18-11-2008 à 14:55:19

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 04-01-2009 à 22:13:30    

Salut en fait la solution de flo850 était ce qu'il me fallait :
SELECT MAX(cours) as max_cours , MIN(cours) as min_cours,id_cotation,date  FROM cours where date>=\"$date1\" and date<=\"$date_fin\" GROUP BY id_cotation ORDER BY (MAX(cours) - MIN(cours))/MIN(cours) DESC
 
Il y a parfois un mauvais classement décroissant mais c'est correct.
Vous pouvez voir le résultat sur mon jeu de foot :
 
footexpert.net
(à droite dans les plus fortes variations du jour)
 
et aussi sur la page club
(en valeurs défilantes)


Message édité par fredex le 04-01-2009 à 22:14:09
Reply

Marsh Posté le 16-01-2009 à 20:25:13    

kao98 a écrit :


Ouais mais non. C'est pas comme ça qu'il faut raisonner.
Il faut se dire que la base peut contenir 0 et donc gérer ce cas particulier plutôt que de faire l'autruche en se disant "jamais il n'y aura de 0".
Une erreur de saisie, une RAZ par erreur, un produit offert (et donc prix=0) à un moment donné (promo particulière, offert avec un autre achat, que sais-je), une fausse manip du DBA, ...


bah il crée une contrainte sur la table qui interdit le 0 et voilà :o

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed