带数组的Bigquery javascript UDF
我正在尝试使用标准SQL和javascript UDF在bigquery中运行下面的查询。查询需要花费很长时间才能运行,因此我甚至无法验证函数是否正常工作。你能告诉我查询是否有任何错误导致它永远运行吗?我试图更改函数调用 从IRRCalcArray[cash_flow],数组[date_delta]作为IRR到IRRCalcArray从输入中选择cash_flow,数组从输入中选择date_delta作为IRR,解决了问题。虽然我不明白IRRCalcArray[现金流]有什么问题,但数组[日期增量]作为IRR。有人能看一看,照点光吗?非常感谢 问题是:带数组的Bigquery javascript UDF,javascript,google-bigquery,user-defined-functions,Javascript,Google Bigquery,User Defined Functions,我正在尝试使用标准SQL和javascript UDF在bigquery中运行下面的查询。查询需要花费很长时间才能运行,因此我甚至无法验证函数是否正常工作。你能告诉我查询是否有任何错误导致它永远运行吗?我试图更改函数调用 从IRRCalcArray[cash_flow],数组[date_delta]作为IRR到IRRCalcArray从输入中选择cash_flow,数组从输入中选择date_delta作为IRR,解决了问题。虽然我不明白IRRCalcArray[现金流]有什么问题,但数组[日期增
CREATE TEMPORARY FUNCTION IRRCalc(cash_flow ARRAY<FLOAT64>, date_delta ARRAY<INT64>)
RETURNS FLOAT64
LANGUAGE js AS """
min = 0.0;
max = 1.0;
do {
guess = (min + max) / 2;
NPV = 0.0;
for (var j=0; j<cash_flow.length; j++){
NPV += cash_flow[j]/Math.pow((1+guess),date_delta[j]/365);
}
if (NPV > 0){
min = guess;
}
else {
max = guess;
}
} while (Math.abs(NPV) > 0.00000001);
return guess * 100;
""";
WITH Input AS
(
select
cash_flow_date,
date_diff(cash_flow_date, min(cash_flow_date) over (),day) as date_delta,
cash_flow as cash_flow
from cash_flow_table
)
SELECT
cash_flow,
date_delta,
IRRCalc(Array<FLOAT64> [cash_flow], ARRAY<INT64> [date_delta]) as IRR
FROM Input;
这是包含原始数据的表格:
行现金流日期增量现金流
1 2017-09-08 0 -159951.78265102694
2 2017-09-08 0 -9.272567110204461
3 2017-09-08 0 -1000.0
4 2017-09-08 0 -159951.78265102694
5 2017-09-27 19 3552.8711640094157
6 2017-09-27 19 -544.122218768042
7 2018-03-28 201 -576.4290755116443
8 2018-03-28 201 3763.8202775817454
9 2018-04-02 206 437225.5536144294
有人能看一看,照点光吗
要查看差异,只需运行SELECT w/o UDF
SELECT
cash_flow,
date_delta,
ARRAY<FLOAT64> [cash_flow],
ARRAY<INT64> [date_delta]
FROM Input
正如您在这里看到的,对于每一行,您创建的数组中只有一个元素,所以实际上是两个数组,每个数组中有一个元素,这些元素分别属于同一行
当您从输入中排列选择现金流,从输入中排列选择日期增量时,您实际上创建了包含所有行中相应元素的数组
最后,当您传递的数组中只有一个元素时,它看起来像您的while Math.absNPV>0.00000001始终为真,因此循环将永远运行
我想是这样的
注意:以上回答了您的确切问题-但您仍然很可能对逻辑有疑问-如果有,请提出新的具体问题您的回答很有意义。谢谢关于循环,我认为我所需要做的就是定义一个iter_cnt并将其添加到…while…,因此当它运行一定数量的循环时,它被迫停止。类似while Math.absNPV>0.00000001&&iter\n抱歉,我在添加评论后进行了跟进。我认为这应该是一个新问题,因为您最初提出的问题至少从我的预期中得到了回答,但是,从另一方面来说,介绍反-简单,应该适合你-所以你可能想简单地尝试,没有必要问它:oThanks。尽管我不确定它在海量数据方面如何工作,但计数器还是起作用了。我会发布一个新的,如果进一步的问题。再次感谢。