我尝试在运行左联接时使用SQL UDF,但是出现以下错误:
联接谓词中的子查询应仅依赖于一个联接端。
查询是:
CREATE TEMPORARY FUNCTION game_match(game1 STRING,game2 STRING) AS (
strpos(game1,game2) >0
);
SELECT
t1.gameId
FROM `bigquery-public-data.baseball.games_post_wide` t1
left join `bigquery-public-data.baseball.games_post_wide` t2 on t1.gameId=t2.gameId and game_match(t1. gameId, t2.gameId)
内联编写条件时,查询可以代替函数调用(strpos(t1. gameId, t2. gameId) >0)
,而有效。
此特定功能是否存在问题,或者联接谓词(由于某些原因)通常不支持SQL UDF?
答案 0 :(得分:1)
您可以在the issue tracker上提交功能请求以完成此工作。这是查询计划/优化的局限性;在某些背景下,BigQuery会转换函数调用,以便查询的逻辑表示像这样:
SELECT
t1.gameId
FROM `bigquery-public-data.baseball.games_post_wide` t1
left join `bigquery-public-data.baseball.games_post_wide` t2
on t1.gameId=t2.gameId
and (SELECT strpos(game1,game2) > 0 FROM (SELECT t1.gameId AS game1, t2.gameId AS game2))
BigQuery这样转换SQL UDF调用的原因是,它需要避免多次计算输入。虽然在这种特定情况下这不是问题,但是如果您在UDF主体中多次引用输入中的一个(例如,考虑这个UDF:
CREATE TEMP FUNCTION Foo(x FLOAT64) AS (x - x);
SELECT Foo(RAND());
如果BigQuery直接内联表达式,您将得到以下结果:
SELECT RAND() - RAND();
结果不会为零,这对于UDF的定义而言是意外的。
在大多数情况下,BigQuery的逻辑优化将如上所示的更复杂的子选择转换为更简单的形式,前提是这样做不会改变查询的语义。但是,在这种情况下并没有发生这种情况,因此是错误。