我不知道这是否可能,但我希望能够创建一个计算列,其中每一行依赖于它上面的行.
一个典型的例子是Fibonacci序列,其中序列由递归关系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
... ...
Run Code Online (Sandbox Code Playgroud)
我希望能够将Fibonacci列构建为计算列.
现在,我知道Fibonacci序列有一个很好的封闭形式,我可以定义
Fibonacci = (((1 + SQRT(5))/2)^[Index] - ((1 - SQRT(5))/2)^[Index])/SQRT(5)
Run Code Online (Sandbox Code Playgroud)
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]
)
Run Code Online (Sandbox Code Playgroud)
但是对于递归定义的函数来说,情况并非如此(或者出于我真正感兴趣的目的).
在Excel中,这很容易做到.你会写一个像这样的公式
A3 = A2 + A1
Run Code Online (Sandbox Code Playgroud)
或者在R1C1表示法中,
= R[-1]C + R[-2]C
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚这是否在DAX中是可能的.
我尝试过的任何东西要么不起作用,要么给出循环依赖性错误.例如,
Fibonacci =
VAR n = [Index]
RETURN
IF(Table1[Index] <= 2,
1,
SUMX(
FILTER(Table1,
Table1[Index] IN {n - 1, n - 2}),
Table1[Fibonacci]
)
)
Run Code Online (Sandbox Code Playgroud)
给出错误消息
检测到循环依赖性:表1 [Fibonacci].
编辑:
在Marco Russo和Alberto Ferrari的Microsoft SQL Server Analysis Services中的表格建模一书中,描述了DAX并包括以下段落:
作为纯函数式语言,DAX没有命令式语句,但它利用称为迭代器的特殊函数,为给定表表达式的每一行执行特定表达式.这些参数接近函数语言中的lambda表达式.但是,组合它们的方式存在限制,因此我们不能说它们对应于通用的lambda表达式定义.尽管DAX具有功能特性,但它不允许您定义新函数并且不提供递归.
似乎没有直接的方法来进行递归.我仍然想知道是否还有一种方法可以间接地以某种方式间接使用父子函数,这看起来本质上是递归的.
根据你的第一个样本数据集,它在我看来就像是“某种”累积总计,它可能可以使用 WINDOW 函数在 SQL 中轻松计算——我尝试了一些方法,但还没有任何结果。我与 DAX 的合作还不够多,无法判断是否可以做到。
编辑:仔细检查一下Fibonacci sequence,发现我的SQL代码进行累积比较是不正确的。您可以阅读SO帖子如何生成斐波那契数列,它有一些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
Run Code Online (Sandbox Code Playgroud)
结果集:
+------+-------------+-----------+
| 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 |
+------+-------------+-----------+
Run Code Online (Sandbox Code Playgroud)
德国DAX指数累计:
可以帮助使用 DAX 计算累积总计的链接 - https://www.daxpatterns.com/cumulative-total/。这是本文中的一些示例代码。
Cumulative Quantity :=
CALCULATE (
SUM ( Transactions[Quantity] ),
FILTER (
ALL ( 'Date'[Date] ),
'Date'[Date] <= MAX ( 'Date'[Date] )
)
)
Run Code Online (Sandbox Code Playgroud)