[MYSQL5] Faire un cumul de valeur

Administrateur PHPfrance
Administrateur PHPfrance | 430 Messages

28 juin 2005, 15:41

Ca me cassais les pieds => je l'ai fait, une fonction qui cumule les valeurs d'un champ numérique.
Pourquoi ne pas le faire dans mon application me direz vous ??? Parceque c'est une de mes contraintes : y'a pas d'application !


pour permettre de lancer plusieurs cumuls dans une même requete, un cumul doit être nommé (on peut par exemple utiliser le nom du champ sur lequel on effectue le cumul)

Il y a deux procédures clear_all_cumul(), clear_one_cumul('nom_du_cumul') et la fonction de cumul proprement dite cumul('nom_du_cumul',valeur)

exécuter le code suivant dans le client mysql.exe (ou équivalent)

Code : Tout sélectionner

DELIMITER $$ DROP PROCEDURE IF EXISTS `clear_all_cumul`$$ CREATE PROCEDURE `clear_all_cumul`() drop temporary table if exists tmp_cumul_func$$ DROP PROCEDURE IF EXISTS `clear_one_cumul`$$ CREATE PROCEDURE `clear_one_cumul`(nomCpt varchar(50)) delete from tmp_cumul_func where nom=nomCpt$$ DROP FUNCTION IF EXISTS `cumul`$$ CREATE FUNCTION `cumul`(nomCpt VARCHAR(50), x REAL) RETURNS REAL BEGIN #variable stockant le total DECLARE tt REAL; #creation de la table stockant les cumuls CREATE TEMPORARY TABLE IF NOT EXISTS tmp_cumul_func ( nom VARCHAR(50), total REAL NOT NULL DEFAULT 0, PRIMARY KEY (nom) ); #calcul du nouveau total INSERT INTO tmp_cumul_func VALUES (nomCpt,x) ON DUPLICATE KEY UPDATE total=total+x ; #recherche du total précédent SELECT total INTO tt FROM tmp_cumul_func WHERE nom=nomCpt; return tt; END$$ DELIMITER ;

Administrateur PHPfrance
Administrateur PHPfrance | 430 Messages

28 juin 2005, 16:14

tin, je suis trop fort !! :lol:
je viens de tomber dans un autre probleme que j'ai résolu avec une sol a deux balles :)

faire des cumuls sur une valeur c'est sympa, mais si on doit faire des *sous cumuls* en fonction d'une autre valeur ???? ben c'est con : on met la valeur en question dans le nom du cumul et ca regle le probleme !

exemple cumul de fréquence et de pourcentage en fonction de la valeur du parametre DMT

Code : Tout sélectionner

SELECT t.*, cumul(CONCAT(t.`DMT`,'_frequence'),t.frequence) AS cumul_frequence, cumul(CONCAT(t.`DMT`,'_pourcentage'),t.pourcentage) AS cumul_pourcentage FROM tmp_tab60_final t;

Administrateur PHPfrance
Administrateur PHPfrance | 430 Messages

04 juil. 2005, 11:29

bon, je ferme ma gueule : c'est faisable avec le SQL de base, mais ca oblige a passer par des tables non temporaires => je suppose que le serveur prend plus de temps vu qu'il faut créer les fichiers de stockage des tables.

Pourquoi par des tables non temporaires ? pke on peut pas croiser une jointure sur une même table temporaire (pas de FROM T1 LEFT JOIN T1)

pkoi moi je passe par des tables temporaires ?
pke j'ai une table d'évènements typés et que je doit faire un cumul par ordre décroissant de fréquence => mon cumul se fait sur un résultat SQL => pas besoin de stockage

Autre probleme : on a souvent le droit de créer des tables temporaires, mais pas forcément celui de créer des tables normales.

Enfin bref, voici la solution :
source : http://sqlpro.developpez.com/cours/sqls ... oidCursor/
soit cle, une cle auto incréementée en fonction de l'ordre de cumul souhaité, DMT, mon type d'évènement et fréquence le nombre d'évènements

Code : Tout sélectionner

SELECT t1.*, SUM(t2.frequence) AS cumul_frequence, FROM table t1 LEFT JOIN table t2 ON t1.DMT=t2.DMT AND t1.cle>=t2.cle GROUP BY t1.DMT, t1.cle;
"... demanda à voir le CV du recruteur pour être sûr que le chef du personnel était compétent".