Quel est l'équivalent de la fonction SUM pour un produit ?

Présentation
MySQL n'a pas de fonction pour agréger par produit. Toutefois, il est possible de le faire avec les fonctions EXP et LN.

Si, par exemple, vous avez la table suivante
CREATE TABLE Exemple (
forme varchar(20),
dimension varchar(10),
facteur float NOT NULL
) ;


Et le jeu de données suivant
INSERT INTO Exemple VALUES('parallélépipède', 'largeur', 10);
INSERT INTO Exemple VALUES('parallélépipède', 'longueur', 30);
INSERT INTO Exemple VALUES('parallélépipède', 'hauteur', 15);
INSERT INTO Exemple VALUES('pyramide', 'base', 20);
INSERT INTO Exemple VALUES('pyramide', 'hauteur', 30);
INSERT INTO Exemple VALUES('pyramide', 'constante', 1/3);


On veut calculer le volume de chaque forme, et donc faire quelque chose comme :

-- erreur de syntaxe
SELECT forme, Produit(facteur) AS Volume
FROM Exemple
GROUP BY forme

Cette requête n'est pas valide parce que la fonction Produit() n'existe pas.
on la remplacera donc par l'exponentiel d'une somme de logarithmes :

SELECT forme, EXP(SUM(LN(facteur))) AS Volume
FROM Exemple
GROUP BY forme
Détails
Avatar de Antoine Dinimant
Rédacteur / Modérateur
Voir tous les téléchargements de l'auteur
Licence : Autre
Date de mise en ligne : 13 février 2011




Avatar de gene69 gene69 - Membre émérite https://www.developpez.com
le 14/02/2011 à 11:01
c'est trivial pour qui a fait des maths. faut voir apres avec quelque exemple si on a pas un probleme de précision de calcul.

ceci dit c'est complètement faux.

le domaine de définition de l'opérateur multiplication c'est celui du corps commutatif dont il participe à la définition.

le domaine de définition de la fonction logarythme c'est R+*, je veux dire c'est réel par beau temps mais strictement positif.

du coup pour être strict il faut au minimum ajouter des valeurs absolues pour traiter le cas des multiplieurs négatifs et faire une condition spéciale pour le cas ou des "opérandes" est nulle.

du coup... faut vraiment voir au cas par cas.
Avatar de pacmann pacmann - Membre émérite https://www.developpez.com
le 08/12/2011 à 14:19
Salut,

Non, c'est pas au cas par cas, tu peux faire ta formule générique.

Code : Sélectionner tout
1
2
 
CASE WHEN MIN(abs(facteur)) = 0 THEN 0 ELSE EXP(SUM(LN(abs(facteur)))) * power(-1, mod(sum(case when facter < 0 then 1 else 0 end, 2)) END
(Non testé, écrit par quelqu'un qui fait de l'Oracle mais on doit pouvoir faire la même chez vous )

Par contre, chuis d'accord sur la précision : à tester ou à démontrer.

[EDIT]
Pour le traitement des nulls, à toi de voir ce que tu veux.
Le NULL est neutre pour sum, donc neutre pour exp(sum(ln()).
Si tu veux qu'il absorbe, tu ajoutes au résultat un facteur qui détecte le NULL et le transforme en 0 (genre min(case when facteur is null then 0 else 1 end))
Avatar de CinePhil CinePhil - Modérateur https://www.developpez.com
le 08/12/2011 à 14:29
Il y a COALESCE pour transformer un NULL en 0 !
Avatar de pacmann pacmann - Membre émérite https://www.developpez.com
le 08/12/2011 à 14:32
C'était pour éviter de faire des abs, mais effectivement ça serait plus joli avec coalesce
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.
Contacter le responsable de la rubrique MySQL