Update Min & Max

Stephanie
Invité n'ayant pas de compte PHPfrance

17 mai 2010, 15:21

Bonjour,

Le but de ma requete consiste a mettre à jour la plus petite valeur d'un champ.
La nouvelle valeur doit être égale à la plus grande valeur du même champ + 1

MIN(monchamp) = MAX(monchamp) + 1

Ex:

monchamp
125
456
741
812

La requête doit donc mettre à jour la valeur 125 => 813
UPDATE matable SET MIN(monchamp) = MAX(monchamp) + 1
Mais ca ne fonctionne pas, et les requête imbriquées non plus

Quelqu'un à une solution ?

Cordialement,
Stéphanie

Mammouth du PHP | 661 Messages

18 mai 2010, 22:39

salut ::
t'as testé avec un truc du style ::
UPDATE matable SET monchamp =  MAX(monchamp) + 1 WEHRE monchamp = MIN(monchamp)
ou
UPDATE matable SET monchamp =  MAX(monchamp) + 1 ORDER BY monchamp ASC LIMIT 1
enfin ... je ne penses pas que cela fonctionne (j'ai plus les neurones pour faire qqch de parfait) mais ce sont des idées en live ^^

Stéphanie
Invité n'ayant pas de compte PHPfrance

19 mai 2010, 15:48

Bonjour,

Les 2 requêtes que tu proposes ne fonctionnent pas
L'erreur retournée est "Invalid use of group function"

Stéphanie

ViPHP
AB
ViPHP | 5818 Messages

19 mai 2010, 18:34

Tu fais deux requêtes successives et tu utilises soit les transactions soit lock table avec les tables myIsam (qui ne supportent pas les transactions)

Mammouth du PHP | 661 Messages

19 mai 2010, 18:49

salut !...
bon, j'ai une solution avec une procédure stockée :: c'est peut-etre pas la meilleur, mais elle effectue ce que tu veux :D

la table que j'ai utilisé est la suivante ::
	idTest	var	var2
	1	1	1
	2	2	1
	3	11	1
	4	15	1
	5	9	1
	6	7	1
	7	13	1
	8	6	1
et la procédure :
CREATE PROCEDURE `incre`()
BEGIN 
DECLARE nb INT; /* variable qui contiendra la valeur à utiliser pour l'UPDATE */
DECLARE id INT; /* variable contenant l'idTest de la ligne qui nous intéresse */
SELECT MAX(var) INTO nb FROM test;
SELECT idTest INTO id FROM test ORDER BY var LIMIT 0,1;
UPDATE test SET var = (nb+1) WHERE idTest = id;
END;
je la fais fonctionner ainsi :
CALL incre();
et tu constatera qu'elle va effectuer le travaille demandé ;)

si tu veux que la procédure te retourne l'id qui à été modifié, tu peux faire ça ::
CREATE PROCEDURE `incre`(OUT id INT)
BEGIN 
DECLARE nb INT; /* variable qui contiendra la valeur à utiliser pour l'UPDATE */
SELECT MAX(var) INTO nb FROM test;
SELECT idTest INTO id FROM test ORDER BY var LIMIT 0,1;
UPDATE test SET var = (nb+1) WHERE idTest = id;
END;
avec comme commandes ::
CALL incre(@a);
SELECT @a ;
tu as toutes les explications sur les procédures MySQL ici ;) Bon courage !

EDIT : oups, j'avais pas vu ta réponse, AB ...

ViPHP
AB
ViPHP | 5818 Messages

19 mai 2010, 20:42

Pour illustrer ce que je disais plus haut, avec une table myIsam la syntaxe "classique" serait :
mysql_query("LOCK TABLES catalogue WRITE");

$query = mysql_query("SELECT MAX(prix) AS 'mx', MIN(prix) AS 'mi' FROM catalogue");

if (mysql_num_rows($query) == 1) 
{
	$result = mysql_fetch_assoc($query);
	
	$query = mysql_query("UPDATE catalogue SET prix = (".$result['mx']." +1) WHERE prix = '".$result['mi']."'");
}

mysql_query("UNLOCK TABLES");
A noter que si tu as deux valeurs minimum identiques elles seront toutes les deux mises à jour.
...et si tu as des nombres décimaux utilises le type DOUBLE et non pas FLOAT.

Stéphanie
Invité n'ayant pas de compte PHPfrance

20 mai 2010, 09:53

Merci à Nours et AB pour vos propositions.

J'ai de quoi étudier. Je n'ai encore jamais utilisée de procédures stockées.

Jusquà présent j'ai toujours cherché à obtenir le résultat avec un minimum de requête.
Dans ce cas, j'ai l'impression, qu'il faut utiliser plus d'une requête, tanpis, je ferais le necessaire.

Cordialement,
Stéphanie.

ViPHP
AB
ViPHP | 5818 Messages

20 mai 2010, 16:02

Si tu utilises les procédures stockées, penses quand même à verrouiller tes tables car sauf erreur de ma part (je ne suis pas spécialiste des procédures stockées) l'un n'implique pas nécessairement l'autre.