MySQL是否有类似于Oracle的“分析函数”(analytic functions)的功能?

18
我正在寻找类似 MySQL 中 PARTITION BY 的分析函数(请参阅文档以获取更多信息)。

分析函数基于一组行计算聚合值。它们与聚合函数不同之处在于,它们为每个组返回多行。

它是否存在?


如果这类似于窗口函数,那么不是的:http://en.wikipedia.org/wiki/Comparison_of_relational_database_management_systems - ripper234
2
如果你想在开源数据库中使用窗口函数,你需要使用PostgreSQL。 - user330315
4个回答

21

我想告诉你,在MySQL中可以使用变量来模拟分析函数。例如,SUM OVER可以按以下方式完成:


SELECT amount, 
    @sum := @sum + amount as sum 
FROM tbl
JOIN (SELECT @sum := 0) s

这段代码是用于查询 `tbl` 表中的 `amount` 字段,并计算它们的总和。使用了 MySQL 中的用户变量 `@sum` 来保存当前的累加值,并在每次迭代时更新该值。`JOIN (SELECT @sum := 0)` 是为了初始化该变量。

如果您想使用 PARTITION BY,这是可能的,但会更加复杂。基本上,您需要添加另一个 @variable 来监控账户(或任何您想要分区的内容),按照账户(或您的变量)排序,然后在账户更改时重置 @sum。如下所示:


SELECT account, 
    amount, 
    (当@account != account时,则@sum := amount,否则@sum := @sum + amount) as sum,
    (当@account != account时,则@account := account,否则@account) as _
FROM (按account排序的SELECT * FROM tbl)
JOIN (SELECT @sum := 0) s
JOIN (SELECT @account := '') a

要实现分区效果,需要进行两个主要改变:

  1. 将主表(tbl)放在一个带有ORDER BY子句的子查询中。这是必要的,因为当MySQL执行@account变量测试时,需要对值进行排序。如果不这样做,您将得到错误的汇总值和账户值。

  2. 存在一个附加的列别名为as _。使用结果时可以忽略此列,但是需要在@sum检查和更改之后进行@account检查和更改。

    另外,如果您不介意将账户列放在最后,还可以重新排列列的顺序。这可以通过删除第一个account列并明确命名别名为account_列来实现。

资源:


4
这应该是被采纳的答案。我不明白为什么它有效,就像魔法一样哈哈。 - Phrancis

17

不,这是MySQL的主要缺点之一,与MSSQL、Oracle、PostgreSQL等其他DBMS相比。我强烈怀疑未来会在MySQL中看到窗口函数,尤其是在Oracle收购MySQL之后...

更新于04/2018

MySQL 8.0现在支持窗口函数了。


1
MySQL 也缺乏递归查询。 - user330315
我是否遗漏了什么,还是这篇文章描述了MySQL的分析函数:http://explainextended.com/2009/03/10/analytic-functions-first_value-last_value-lead-lag/? - Jens Schauder
1
啊,现在我明白了,它描述的是分析函数,然后又描述了如何在MySQL中实现类似的结果,但不使用它们。 - Jens Schauder

0

尽管MySQL不支持分析函数,MariaDB支持。它是MySQL的一个可替代品,由MySQL的原始开发人员创建。


这个答案已经过时了:https://dev.mysql.com/doc/refman/8.0/en/window-functions.html - Lukas Eder

-5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接