问题描述
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
表的列。