Necesito una función agregada que MySQL no proporciona.
Me gustaría que estuviera en el sabor de SQL de MySQL (es decir, no en C).
¿Cómo hago esto? Lo que estoy atascado es crear una función agregada; los documentos no parecen mencionar cómo se hace.
Ejemplos del uso deseado de una product
función:
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)
No sé si hay forma de definir una nueva función agregada, no sin jugar con el código fuente de MySQL.
Pero si todos sus números son positivos, bien puede derivar de la identidad aritmética:
que puedes usar
EXP(SUM(LOG(x)))
para calcularPRODUCT(x)
. Prueba en SQL-Fiddle :Cuando los datos pueden tener ceros, se vuelve un poco más complicado:
Probado en SQL-Fiddle
Para otros DBMS, que no tienen la conversión automática de valores booleanos a enteros de MySQL, el
debe reemplazarse con:
Específicamente para Oracle, se necesitarán algunos cambios más, sin cambiar la lógica de la respuesta, solo porque Oracle no sigue el estricto estándar ANSI en algunas áreas. Probado en SQL-Fiddle-2
fuente
product
se suponía que era un ejemplo de varios.PRODUCT(..., 0, ...) = 0
, queremos esoEXP(SUM(..., f(0), ...)) = 0
, para algunosf
que elegimos, pero para satisfacer esto, necesitamos esoSUM(..., f(0), ...) = LOG(0)
, nuevamente frustrado por el mismo problema que log (0 ) es indefinido. Necesitamos verificar la presencia de cero de alguna otra manera, por ejemploMIN(ABS(a)) = 0
. Entonces lo habríamos hechoSELECT CASE WHEN MIN(ABS(a)) = 0 THEN 0 ELSE EXP(SUM(LOG(a))) END AS product
. ¿Es este el tipo de cosas en las que estabas pensando?En aras de aprender a pescar, he compilado e instalado con éxito un "¡Hola, mundo!" UDF (función definida por el usuario) para MySQL que se encuentra aquí . El archivo hello_world.so (después de cumplirlo
gcc -shared -o hello_world.so -I /usr/include/mysql hello_world.c
) debe almacenarse en / usr / lib / mysql / plugins / con 755 permisos en los sistemas Linux de Ubuntu. ["-I / usr / include / mysql" es la ruta a los archivos de encabezado mysql; Descubrí que mi código no se compilaría sin este parámetro, pero YMMV.]El programa no hace más que imprimir la cadena "¡Hola, mundo!" para cada registro en el conjunto de datos resultante de una consulta, pero eso es todo lo que se supone que debe hacer. Intentaré escribir una función agregada PEQUEÑA en los próximos días. Hay un ejemplo de una función agregada que calcula el costo promedio de un grupo de registros de precio y cantidad; la función PEQUEÑA no debería ser tan diferente de esa función al final.
Espero que esto ayude.
fuente