Trouver le plus grand ecart entre 2 valeurs - SQL/NoSQL - Programmation
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
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
Marsh Posté le 18-11-2008 à 09:48:32
pourquoi tu divises ?
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 ?
Marsh Posté le 18-11-2008 à 10:18:48
flo850 a écrit : SELECT MAX(prix) , MIN(prix) , id |
select (max(prix) - min(prix)) as ecart ça marche pas?
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.
Encore une fois merci beaucoup pour votre aide.
Marsh Posté le 18-11-2008 à 10:55:24
ReplyMarsh Posté le 18-11-2008 à 10:56:52
gzii a écrit : Ca doit être sympa quand la valeur min est à zéro |
c'est rare que tu vendes un truc zéro.
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.
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 ?
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)
Marsh Posté le 18-11-2008 à 11:29:47
fredax a écrit : merci flo850 pour vos aide. |
WHERE date > '$dateDebut' and date < '$dateFin'
ou
WHERE date BETWEEN '$dateDebut' AND '$datefin'
Marsh Posté le 18-11-2008 à 11:31:08
fredax a écrit : merci flo850 pour vos aide. SELECT MAX(prix) AS max_prix , MIN(prix) AS min_prix, id,date Ca me fait un bon trie des prix des plus grands écarts mais pas des plus grands écarts entre date_debut et date_fin. 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.) :
Code :
|
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, ...
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
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.
Marsh Posté le 18-11-2008 à 13:33:17
flo850 a écrit : pour avoir un pourcentage de variation |
j'avais compris, mais ça n'est pas la bonne formule pour le faire !
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.
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 |
oui mais alors si tu nous donnes pas toutes les infos on va pas faire de miracle. Montre ton vrai code.
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+
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";
}
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?
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) ...
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.
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.
Marsh Posté le 18-11-2008 à 14:54:58
fredax a écrit : 1) j'utilise mysql_db_query parceque je me connecte avec 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 |
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
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)
Marsh Posté le 16-01-2009 à 20:25:13
kao98 a écrit : |
bah il crée une contrainte sur la table qui interdit le 0 et voilà
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+