【问题标题】:Recursion in DAXDAX 中的递归
【发布时间】:2019-03-16 21:18:40
【问题描述】:

我不知道这是否可能,但我希望能够创建一个计算列,其中每一行都依赖于它上面的行。

一个典型的例子是Fibonacci sequence,其中的序列由递归关系F(n) = F(n-1) + F(n-2)和种子F(1) = F(2) = 1定义。

表格形式,

Index  Fibonacci
----------------
 1      1
 2      1
 3      2
 4      3
 5      5
 6      8
 7     13
 8     21
 9     34
10     55
...    ...

我希望能够将Fibonacci 列构造为计算列。

现在,我知道斐波那契数列有一个很好的封闭形式,我可以在其中定义

Fibonacci = (((1 + SQRT(5))/2)^[Index] - ((1 - SQRT(5))/2)^[Index])/SQRT(5)

或使用shallow diagonals of Pascal's triangle form:

Fibonacci =
SUMX (
    ADDCOLUMNS (
        SELECTCOLUMNS (
            GENERATESERIES ( 0, FLOOR ( ( [Index] - 1 ) / 2, 1 ) ),
            "ID", [Value]
        ),
        "BinomCoeff", IF (
            [ID] = 0,
            1,
            PRODUCTX (
                GENERATESERIES ( 1, [ID] ),
                DIVIDE ( [Index] - [ID] - [Value], [Value] )
            )
        )
    ),
    [BinomCoeff]
)

但对于一般递归定义的函数(或出于我真正感兴趣的目的),情况并非如此。


在 Excel 中,这很容易做到。你会写一个这样的公式

A3 = A2 + A1

或在 R1C1 表示法中,

= R[-1]C + R[-2]C

但我就是不知道这在 DAX 中是否可行。

我尝试过的所有方法都不起作用或出现循环依赖错误。例如,

Fibonacci = 
VAR n = [Index]
RETURN
IF(Table1[Index] <= 2,
    1,
    SUMX(
        FILTER(Table1,
            Table1[Index] IN {n - 1, n - 2}),
        Table1[Fibonacci]
    )
)

给出错误信息

检测到循环依赖:Table1[Fibonacci]。


编辑:

在 Marco Russo 和 Alberto Ferrari 所著的 Microsoft SQL Server Analysis Services 中的表格建模一书中,DAX 被描述并包含以下段落:

作为一种纯函数式语言,DAX 没有命令式语句,但它利用称为 iterators 的特殊函数为给定表表达式的每一行执行特定表达式。这些参数接近函数式语言中的 lambda 表达式。但是,组合它们的方式存在限制,因此我们不能说它们对应于通用 lambda 表达式定义。尽管具有函数性质,但 DAX 不允许您定义新函数并且不提供递归。

似乎没有直接的方法来进行递归。我仍然想知道是否有办法以某种方式使用Parent-Child functions 间接地做到这一点,这在本质上似乎是递归的。


编辑 2:

虽然一般递归似乎不可行,但不要忘记递归公式可能有一个很好的封闭形式,可以相当容易地推导出来。

以下是我使用此解决方法来回避递归公式的几个示例:

How to perform sum of previous cells of same column in PowerBI

DAX - formula referencing itself

【问题讨论】:

    标签: dax


    【解决方案1】:

    根据您的第一个示例数据集,它在我看来就像“某种”累积总计,它可能可以使用 WINDOW 函数在 SQL 中轻松计算——我尝试了几件事,但没有任何结果刚刚出来。我与 DAX 的合作不足以说明它是否可以完成。

    编辑:在仔细查看Fibonacci sequence 时,发现我的SQL 代码进行累积比较是不正确的。你可以阅读 SO Post How to generate Fibonacci Series,它有一些我测试过的很好的SQL Fibonacci 答案;特别是N J - answered Feb 13 '14 的帖子。我不确定DAX Fibonacci 递归函数的能力。


    SQL 代码(不太正确):

    DECLARE @myTable as table (Indx int)
    
    INSERT INTO @myTable VALUES
        (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
    
    SELECT
        Indx
        ,SUM(myTable.Indx) OVER(ORDER BY myTable.Indx ASC ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) -- + myTable.Indx
            AS [Cummulative]
        ,SUM(myTable.Indx) OVER(ORDER BY myTable.Indx ASC ROWS BETWEEN UNBOUNDED PRECEDING and 2 PRECEDING) 
            + SUM(myTable.Indx) OVER(ORDER BY myTable.Indx ASC ROWS BETWEEN UNBOUNDED PRECEDING and 1 PRECEDING) 
            AS [Fibonacci]
    from @myTable myTable
    

    结果集:

    +------+-------------+-----------+
    | Indx | Cummulative | Fibonacci |
    +------+-------------+-----------+
    | 1    | 1           | NULL      |
    +------+-------------+-----------+
    | 2    | 3           | NULL      |
    +------+-------------+-----------+
    | 3    | 6           | 4         |
    +------+-------------+-----------+
    | 4    | 10          | 9         |
    +------+-------------+-----------+
    | 5    | 15          | 16        |
    +------+-------------+-----------+
    | 6    | 21          | 25        |
    +------+-------------+-----------+
    | 7    | 28          | 36        |
    +------+-------------+-----------+
    | 8    | 36          | 49        |
    +------+-------------+-----------+
    | 9    | 45          | 64        |
    +------+-------------+-----------+
    | 10   | 55          | 81        |
    +------+-------------+-----------+
    

    DAX 累积:

    可以帮助计算 DAX 累积总数的链接--https://www.daxpatterns.com/cumulative-total/。这是文章中的一些示例代码。

    Cumulative Quantity :=
    CALCULATE (
        SUM ( Transactions[Quantity] ),
        FILTER (
            ALL ( 'Date'[Date] ),
            'Date'[Date] <= MAX ( 'Date'[Date] )
        )
    )
    

    【讨论】:

    • You're Cumulative column 是三角形数序列 Indx*(Indx+1)/2(将前面的 all 相加),而您的 Fibonacci column 是正方形数序列 @987654334 @。都不匹配斐波那契数列。
    • @AlexisOlson- 我在 SQL 中对 SO 解决方案的回答中添加了一个链接。抱歉,我无法创建 DAX 解决方案。在 DAX 中执行此操作的情况是什么?
    • 这是 Excel 数据透视表和 Power BI 使用的语言。我不能对那些使用 SQL。
    【解决方案2】:

    DAX 语言不支持递归。

    也写在sqlbi的一篇关于计算组的文章中

    DAX 不是递归的,因此计算组不允许递归。这是控制性能的好主意,但与 MDX Script 中可能通过利用递归的某些技术相比,它需要一种不同的方法。

    https://www.sqlbi.com/blog/marco/2019/03/01/calculation-groups-in-dax-first-impressions/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-22
      相关资源
      最近更新 更多