Google BigQuery:功能中的“相关子查询”错误

问题描述

我编写了一个函数获取订单的净收入:

CREATE OR REPLACE FUNCTION
  `project.dataset.function`(inputBuyerCurrency STRING,inputCountryCode STRING,inputPrice FLOAT64,inputOrderTimestamp TIMESTAMP)
  RETURNS FLOAT64 AS ( (
    SELECT
      P
    FROM (
      SELECT
        AVG(APP.Proceeds) AS P,App.InsertedTimestamp
      FROM
        `project.dataset.lookup` APP
      LEFT JOIN
        `project.dataset.countrycode_lookup` CC
      ON
        APP.Region = CC.Alpha3
      WHERE
        CC.Alpha2 = inputCountryCode
        AND App.Currency = inputBuyerCurrency
        AND App.Price = inputPrice / 100
        AND App.InsertedTimestamp <= inputOrderTimestamp
      GROUP BY
        App.InsertedTimestamp
      ORDER BY
        InsertedTimestamp DESC
      LIMIT
        1)) );

参数是不言自明的;下单所用的货币、买家所在的国家/地区、下单的价格和时间戳。

project.dataset.lookup 表每天都会使用新的 NetRevenue 值进行更新。我想要的是在下订单之前检查 project.dataset.lookup 中最后一个匹配的行。因此,2021-01-01 22:00:00 的顺序(例如)应该与 InsertTimestamp 的 2021-01-01 01:00:00 匹配。

当我使用硬编码值“调用函数时,不会出现任何问题。我得到了我想要的结果。但是,当我尝试使用表中的值调用函数时,出现以下错误不支持引用其他表的相关子查询,除非它们可以去相关,例如通过将它们转换为有效的 JOIN ..

所以,这是有效的:

SELECT `project.dataset.function`("EUR","NL",1999,1626269392)

但这不会:

SELECT `project.dataset.function`(CurrencyCode,CountryCode,Price,Timestamp)
FROM `project.dataset.order`

非常感谢。

解决方法

假设您的 order 表有 1M 行……您的函数将执行其查询 1M 次,每行一次,这太疯狂了。这是相关子查询。当您将值硬编码到您的函数中时,它实际上只运行了 1 次。

考虑将您的“子查询”变成一个视图,并包含要连接回您的 order 表的列。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...