【问题标题】:Why does this Snowflake query work without requiring the LATERAL keyword?为什么这个 Snowflake 查询不需要 LATERAL 关键字就可以工作?
【发布时间】:2021-07-18 08:49:55
【问题描述】:

我在雪花中有这个视图:

create or replace view foo as 
select $1 as id_foo, $2 as sales
  from (values (1,100),(2,200),(3,300));

还有这个user-defined table function

CREATE OR REPLACE FUNCTION build_aux_table ( restriction number )
  RETURNS TABLE ( aux_id number )
  AS 'select $1 as aux_id from (VALUES (1),(2),(3)) where aux_id = restriction';

以下查询有效,并返回 3 行:

 select id_foo, baz.aux_id
  from foo
 cross join table(build_aux_table(foo.id_foo)) baz;

但是,我没想到查询会编译,因为我们要加入的 UDTF 生成的表依赖于第一个表中的列。我的理解是,这种表内依赖需要LATERAL 连接,如下所示(也可以):

select id_foo, baz.aux_id
  from foo
 cross join lateral build_aux_table(foo.id_foo) baz; 

为什么没有 LATERAL 的查询会起作用?

【问题讨论】:

  • 好地方。我希望有同样的行为:Table Functions"Table functions can also be applied to a set of rows using the LATERAL construct."
  • @LukaszSzozda 奇怪的是,FLATTEN 关键字被描述为一个表函数,但它确实需要 FLATTEN。

标签: sql snowflake-cloud-data-platform lateral-join


【解决方案1】:

Snowflake 手册中没有明确提及(至少在您链接到的地方),但 LATERAL 关键字对于 函数 是可选的,这是标准行为。引用PostgreSQL manual:

FROM中出现的表函数也可以在key前面 字词LATERAL,但对于函数,关键字是可选的;这 函数的参数可以包含对提供的列的引用 在任何情况下都在 FROM 项之前。

粗体强调我的。

也有道理,恕我直言。如果不是从其他表中,函数将在哪里获取其参数?将仅限于没有横向参考的手动输入。

【讨论】:

  • 另一种参数来源可能是副作用,例如获取当前时间戳或生成一些随机值(但也许视图也可以在那里工作)。
  • @danidiaz:有用的应用程序。但是,如果不是FROM 子句中的横向表(表表达式),reference 会指向哪里?
【解决方案2】:

代码:

select id_foo, baz.aux_id
from foo
cross join table(build_aux_table(foo.id_foo)) baz;

基本相同:

select id_foo, baz.aux_id
from foo
,table(build_aux_table(foo.id_foo)) baz;

文档中有描述:

Calling JavaScript UDTFs in Queries

这个简单的示例展示了如何调用 UDTF。此示例传递文字值。

SELECT * FROM TABLE(js_udtf(10.0::FLOAT, 20.0::FLOAT));

此示例调用 UDTF 并将其从另一个表传递值。 在此示例中,名为 js_udtf 的 UDTF 对名为 tab1 的表中的每一行调用一次。 每次调用该函数时,都会从当前行的 c1 和 c2 列传递值。

SELECT * FROM tab1, TABLE(js_udtf(tab1.c1, tab1.c2)) ;

Sample UDTFs - Examples with joins

在与另一个表的连接中使用 UDTF; 请注意,表中的连接列作为参数传递给函数。

select * 
from favorite_years y join table(favorite_colors(y.year)) c;

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 2019-06-22
    • 2011-08-27
    • 1970-01-01
    • 2019-05-16
    • 2020-05-20
    • 1970-01-01
    • 2014-03-30
    相关资源
    最近更新 更多