1

我正在将一些计算从 Google 表格迁移到 BigQuery,并且需要编写一个 SUMPRODUCT 脚本来偏移每一行。

这是 Google 表格中的数据。Column_1, Column_2 给出,SUMPRODUCT 是一个计算:

Column_1 Column_2 SUMPRODUCT
   0         1        0
   5         0        10
   0         1        0
   5         0        5

第 1 列从单元格 A1 开始。

每行的 SUMPRODUCT 公式如下:

=SUMPRODUCT(A2:A5,$B$2:$B$5)
=SUMPRODUCT(A3:A6,$B$2:$B$5)
=SUMPRODUCT(A4:A7,$B$2:$B$5)
=SUMPRODUCT(A5:A8,$B$2:$B$5)

在 Biquery 中,我可以使用 SELECT SUM (column_1 * column_2) AS SUMPRODUCT FROM Table_1 创建第一个 SUMPRODUCT 行

在此之后,每行偏移第 1 列数组具有挑战性。我的最终数据集将有 500 多行我需要这样做。我也尝试过在 SQL 中使用 OFFSET 函数,但遇到了错误。

4

2 回答 2

1

以下是 BigQuery 标准 SQL

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 0 pos, 0 Column_1, 1 Column_2 UNION ALL
  SELECT 1, 5, 0 UNION ALL
  SELECT 2, 0, 1 UNION ALL
  SELECT 3, 5, 0 
), b AS (
  SELECT pos, Column_2 FROM `project.dataset.table`
)
SELECT 
  pos, Column_1, Column_2,
  (SELECT SUM(Column_1 * Column_2)
    FROM UNNEST(a) WITH OFFSET AS pos
    JOIN b USING(pos)  
  ) SUMPRODUCT
FROM (
  SELECT *, 
    ARRAY_AGG(Column_1) OVER(ORDER BY pos ROWS BETWEEN CURRENT ROW AND 3 FOLLOWING) a
  FROM `project.dataset.table` t
)

结果

Row pos Column_1    Column_2    SUMPRODUCT   
1   0   0           1           0    
2   1   5           0           10   
3   2   0           1           0    
4   3   5           0           5    

正如你从上面看到的 - 你必须有一些字段将在工作表中扮演行号的角色 - 在我的回答中,我以pos列为例

于 2019-10-03T23:07:23.150 回答
0

作为与@Mikhail 的回答略有不同的方法,您可以使用 BigQuery 中提供的基于 JS 的外部 UDF 来简化这些任务:

CREATE TEMP FUNCTION sumproduct(column_1 array<int64>, column_2 array<int64>)
RETURNS int64
LANGUAGE js AS """
  output = 0;
  for (var i=0; i<column_1.length; i++){
     output += (column_1[i]*column_2[i]);
  }
  return output;
""";

with sumproducts as (
  select 
     row_number() over () as idx, 
     sumproduct(aggs, b) as sp from (
        select 
           array_agg(column_1) over (order by idx rows between current row and 3 following) aggs, 
           array_agg(column_2) over () b 
        from (
           select row_number() over () as idx, column_1, column_2 from `dataset.table`
        )
     )
),
items as (
   select row_number() over() as idx, column_1, column_2 from `dataset.table`
)

select r.column_1, r.column_2, spd.sp from items r join sumproducts spd on r.idx = spd.idx

希望能帮助到你。

于 2019-10-04T04:03:06.427 回答