J'ai besoin d'une fonction d'agrégation que MySQL ne fournit pas.
Je voudrais que ce soit dans la version MySQL de SQL (c'est-à-dire pas en C).
Comment puis-je faire cela? Ce que je suis bloqué, c'est la création d'une fonction d'agrégation - les documents ne semblent pas mentionner comment cela est fait.
Exemples d'utilisation souhaitée d'une product
fonction:
mysql> select product(col) as a from `table`;
+------+
| a |
+------+
| 144 |
+------+
1 row in set (0.00 sec)
mysql> select col, product(col) as a from `table` group by col;
+-----+------+
| col | a |
+-----+------+
| 6 | 36 |
| 4 | 4 |
+-----+------+
2 rows in set (0.01 sec)
Je ne sais pas s'il existe un moyen de définir une nouvelle fonction d'agrégation, non sans jouer avec le code source de MySQL.
Mais si vos chiffres sont tous positifs, vous pouvez très bien dériver de l'identité arithmétique:
que vous pouvez utiliser
EXP(SUM(LOG(x)))
pour calculerPRODUCT(x)
. Test dans SQL-Fiddle :Lorsque les données peuvent avoir des 0, cela devient un peu plus compliqué:
Testé chez SQL-Fiddle
Pour les autres SGBD, qui n'ont pas la conversion automatique de MySQL des valeurs booléennes en entiers, le
devrait être remplacé par:
Spécifiquement pour Oracle, quelques modifications supplémentaires seront nécessaires, sans changer la logique de la réponse, uniquement parce qu'Oracle ne suit pas la norme ANSI stricte dans certains domaines. Testé à SQL-Fiddle-2
la source
product
était juste censé être un exemple de plusieurs.PRODUCT(..., 0, ...) = 0
, nous voulons queEXP(SUM(..., f(0), ...)) = 0
, pour certainsf
que nous choisissons, mais pour satisfaire, nous avons besoin queSUM(..., f(0), ...) = LOG(0)
- encore une fois contrariée par la même question que log (0 ) n'est pas défini. Nous devons vérifier la présence de zéro d'une autre manière, par exempleMIN(ABS(a)) = 0
. Nous aurions doncSELECT CASE WHEN MIN(ABS(a)) = 0 THEN 0 ELSE EXP(SUM(LOG(a))) END AS product
. Est-ce le genre de chose à laquelle vous pensiez?Dans le but d'apprendre à pêcher, j'ai réussi à compiler et à installer un "Hello, World!" UDF (fonction définie par l'utilisateur) pour MySQL trouvée ici . Le fichier hello_world.so (après avoir été respecté
gcc -shared -o hello_world.so -I /usr/include/mysql hello_world.c
) doit être stocké dans / usr / lib / mysql / plugins / avec 755 autorisations sur les systèmes Linux Ubuntu. [Le "-I / usr / include / mysql" est le chemin d'accès aux fichiers d'en-tête mysql; J'ai trouvé que mon code ne compilerait pas sans ce paramètre, mais YMMV.]Le programme ne fait qu'imprimer la chaîne "Hello, World!" pour chaque enregistrement dans l'ensemble de données résultant d'une requête, mais c'est tout ce qu'il est censé faire. J'essaierai d'écrire une petite fonction d'agrégation dans les prochains jours. Il existe un exemple de fonction agrégée qui calcule le coût moyen d'un groupe d'enregistrements de prix et de quantité; la fonction SMALL ne devrait pas être si différente de cette fonction à la fin.
J'espère que cela t'aides.
la source