如何创建用户定义的聚合函数?

Mat*_*ick 9 mysql aggregate functions

我需要一个 MySQL 不提供的聚合函数。

我希望它具有 MySQL 的 SQL 风格(即,不是在 C 中)。

我该怎么做呢?我所坚持的是创建一个聚合函数——文档似乎没有提到这是如何完成的。

product函数的期望用法示例:

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)
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 10

我不知道是否有办法定义一个新的聚合函数,而不是弄乱 MySQL 源代码。

但是如果你的数字都是正数,你很可能从算术恒等式中推导出来:

log( product( Ai ) ) = sum( log( Ai ) )
Run Code Online (Sandbox Code Playgroud)

您可以使用它EXP(SUM(LOG(x)))来计算PRODUCT(x). 在SQL-Fiddle 中测试:

SELECT EXP(SUM(LOG(a))) AS product
FROM t ;

SELECT col, EXP(SUM(LOG(a))) AS product
FROM t 
GROUP BY col ;
Run Code Online (Sandbox Code Playgroud)

当数据可以有 0 时,它会变得有点复杂:

SELECT (NOT EXISTS (SELECT 1 FROM t WHERE a = 0)) 
       * EXP(SUM(LOG(a))) AS p
FROM t 
WHERE a > 0 ;

SELECT d.col, 
       (NOT EXISTS (SELECT 1 FROM t AS ti WHERE ti.col = d.col AND ti.a = 0)) 
       * COALESCE(EXP(SUM(LOG(t.a))),1)  AS p
FROM 
    ( SELECT DISTINCT col
      FROM t
    ) AS d
  LEFT JOIN
    t  ON  t.col = d.col
       AND t.a > 0
GROUP BY d.col ;
Run Code Online (Sandbox Code Playgroud)

SQL-Fiddle测试


对于其他没有 MySQL 将布尔值自动转换为整数的 DBMS,

(NOT EXISTS (SELECT ...))
Run Code Online (Sandbox Code Playgroud)

应替换为:

(CASE WHEN EXISTS (SELECT 1...) THEN 0 ELSE 1 END) 
Run Code Online (Sandbox Code Playgroud)

专门针对Oracle,需要多做一些改动,不改变答案的逻辑,只是因为Oracle在某些方面没有遵循严格的ANSI标准。在SQL-Fiddle-2测试

  • 那真好;那真甜。高中数学又回来困扰我了。+1 !!! (2认同)

Col*_*art 7

根据文档http://dev.mysql.com/doc/refman/5.5/en/adding-udf.html只能用 C 编写聚合函数。对不起!


Jef*_*and 5

为了学习钓鱼,我已经成功编译安装了一个“Hello, World!” 在这里找到MySQL 的 UDF(用户定义函数)。hello_world.so 文件(编译后gcc -shared -o hello_world.so -I /usr/include/mysql hello_world.c)应存放在/usr/lib/mysql/plugins/ 中,Ubuntu linux 系统755 权限。[“-I /usr/include/mysql”是mysql头文件的路径;我发现如果没有这个参数,我的代码将无法编译,但是 YMMV。]

该程序除了打印出字符串“Hello, World!”之外什么都不做。对于查询结果数据集中的每条记录,但这就是它应该做的。我会在接下来的几天里尝试写一个 SMALL 聚合函数。有一个聚合函数的例子,它计算一组价格和数量记录的平均成本;SMALL 函数最终不应该与那个函数有什么不同。

希望这可以帮助。