带数组的 Bigquery javascript UDF

sl0*_*007 5 javascript user-defined-functions google-bigquery

我正在尝试使用标准 SQL 和 javascript UDF 在 bigquery 中运行以下查询。该查询需要永远运行,因此我什至无法验证该函数是否正常工作。如果查询有任何问题导致它永远运行,您能告诉我吗?我尝试将函数调用从 更改为IRRCalc(Array<FLOAT64> [cash_flow], ARRAY<INT64> [date_delta]) as IRRIRRCalc(array(select cash_flow from input),array(select date_delta from input)) as IRR解决了问题。虽然我不明白有什么问题IRRCalc(Array<FLOAT64> [cash_flow], ARRAY<INT64> [date_delta]) as IRR。有人可以看一下并透露一些信息吗?非常感谢。

这是查询:

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

这是包含原始数据的表:

行 cash_flow_date date_delta cash_flow
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.55 36144294

Mik*_*ant 4

有人可以看一下并透露一些信息吗?

看看差异 - 只需运行 SELECT w/o UDF

SELECT 
  cash_flow,
  date_delta,
  ARRAY<FLOAT64> [cash_flow], 
  ARRAY<INT64> [date_delta]
FROM Input
Run Code Online (Sandbox Code Playgroud)

正如您在这里所看到的 - 对于每一行,您创建的数组中只有一个元素 - 所以实际上是两个数组,每个数组中都有一个元素 - 该元素分别属于同一行

当你这样做时,ARRAY(SELECT cash_flow FROM input), ARRAY(SELECT date_delta FROM input)你实际上创建了包含所有行中各自元素的数组

最后 - 当你传递仅包含一个元素的 ARRAY 时 - 看起来你while (Math.abs(NPV) > 0.00000001)总是 true 因此循环永远运行

我认为沿着这些思路

注意:上面回答了您的确切问题 - 但您很可能仍然存在逻辑问题 - 如果是这样 - 提出新的具体问题