Snowflake SQL udf 的输入列表
Input list to Snowflake SQL udf
我创建了一个 Snowflake SQL udf,我使用以下代码调用:
select *
from table(drill_top_down('12345','XXX)) order by depth,path;
如果我需要运行查询多个项目,是否可以输入一个列表或类似于 udf,然后循环遍历我的输入列表?
或者我能否以更智能的方式调用我的函数,以便从多个输入中获取结果?
您可以提供嵌套了参数集的 Snowflake 数组、对象或变体,并将其用作 table 函数的输入。
调整您的示例,使用数组构造提供两组参数,输入看起来像:
select *
from table(drill_top_down(
array_construct(
array_construct('12345','XXX'),
array_construct('67890','YYY')
)::array;
或者我更喜欢使用 parse_json,因为我觉得它更容易阅读
select *
from table(drill_top_down(parse_json('
[ ["12345","XXX"],
["67890","YYY"] ]')::array;
您将需要调整您的 Table 函数以使用通用 table 表达式 (CTE) 将参数集解包以将输入参数表格化,然后使用 Lateral Flatten 取消嵌套。
这是一个简单的例子:
CREATE OR REPLACE FUNCTION array_concat ( arr array)
RETURNS TABLE ( concatenated_string varchar )
AS
$$
With a as (Select arr)
Select listagg(value)
From a, table(flatten(input => arr))
$$
;
这是一个稍微复杂一些的示例,它对每个参数集执行操作,使用 row_number() 对它们进行分组。
CREATE OR REPLACE FUNCTION array_calcs ( arg_list array)
RETURNS TABLE
( arg_id integer,
array_sz integer,
array_sum integer,
array_mean decimal(12,2) )
AS
$$
With
-- CTE containing the ARGS
arg_input as (select arg_list),
-- CTE un-nest (flatten) first level of args list to each args set
arg_sets as
(Select row_number() over (order by NULL desc) as arg_id, value as arg_set
From arg_input, lateral flatten(input => arg_list))
-- Do something with the Args. e.g. Perform some calculations with the Input arguments
Select arg_id , count(*) array_sz, sum(value)::integer array_sum, array_sum/array_sz::decimal(12,2) array_mean
From arg_sets, table(flatten(input => arg_set))
Where is_decimal( value ) or is_integer( value ) or is_double( value ) -- filter out non-numeric arguments i.e. validate inputs
Group By arg_id
$$;
如果我们提供以下输入参数,这将起作用
Select * from table(array_calcs(parse_json('[ [1],
[1,2],
[1,2,3],
[1,2,3,4],
["A","B"],
["A",1]
]')::array));
生成以下内容:
ARG_ID
ARRAY_SZ
ARRAY_SUM
ARRAY_MEAN
1
1
1
1.0
2
2
3
1.5
3
3
6
2.0
4
4
10
2.5
6
1
1
1.0
但请注意。如果您的目标是直接从您的数据构建您的参数,而不是在函数调用中对它们进行硬编码,您很可能 运行 进入这个问题:
Create or replace View V_array_calcs_input as
Select parse_json()::array arg_list
from (values ('[[1],[1,2],[1,2,3],[1,2,3,4],["A","B"], ["A",1]'));
Select *
from V_array_calcs_input,
table(array_calcs(arg_list));
SQL编译错误:无法计算不支持的子查询类型
存储过程或 JavaScript UDF/UDTF 可能是解决此问题的更好选择,如果您可以在其中任何一个中构建所需的功能逻辑。
我创建了一个 Snowflake SQL udf,我使用以下代码调用:
select *
from table(drill_top_down('12345','XXX)) order by depth,path;
如果我需要运行查询多个项目,是否可以输入一个列表或类似于 udf,然后循环遍历我的输入列表?
或者我能否以更智能的方式调用我的函数,以便从多个输入中获取结果?
您可以提供嵌套了参数集的 Snowflake 数组、对象或变体,并将其用作 table 函数的输入。
调整您的示例,使用数组构造提供两组参数,输入看起来像:
select *
from table(drill_top_down(
array_construct(
array_construct('12345','XXX'),
array_construct('67890','YYY')
)::array;
或者我更喜欢使用 parse_json,因为我觉得它更容易阅读
select *
from table(drill_top_down(parse_json('
[ ["12345","XXX"],
["67890","YYY"] ]')::array;
您将需要调整您的 Table 函数以使用通用 table 表达式 (CTE) 将参数集解包以将输入参数表格化,然后使用 Lateral Flatten 取消嵌套。
这是一个简单的例子:
CREATE OR REPLACE FUNCTION array_concat ( arr array)
RETURNS TABLE ( concatenated_string varchar )
AS
$$
With a as (Select arr)
Select listagg(value)
From a, table(flatten(input => arr))
$$
;
这是一个稍微复杂一些的示例,它对每个参数集执行操作,使用 row_number() 对它们进行分组。
CREATE OR REPLACE FUNCTION array_calcs ( arg_list array)
RETURNS TABLE
( arg_id integer,
array_sz integer,
array_sum integer,
array_mean decimal(12,2) )
AS
$$
With
-- CTE containing the ARGS
arg_input as (select arg_list),
-- CTE un-nest (flatten) first level of args list to each args set
arg_sets as
(Select row_number() over (order by NULL desc) as arg_id, value as arg_set
From arg_input, lateral flatten(input => arg_list))
-- Do something with the Args. e.g. Perform some calculations with the Input arguments
Select arg_id , count(*) array_sz, sum(value)::integer array_sum, array_sum/array_sz::decimal(12,2) array_mean
From arg_sets, table(flatten(input => arg_set))
Where is_decimal( value ) or is_integer( value ) or is_double( value ) -- filter out non-numeric arguments i.e. validate inputs
Group By arg_id
$$;
如果我们提供以下输入参数,这将起作用
Select * from table(array_calcs(parse_json('[ [1],
[1,2],
[1,2,3],
[1,2,3,4],
["A","B"],
["A",1]
]')::array));
生成以下内容:
ARG_ID | ARRAY_SZ | ARRAY_SUM | ARRAY_MEAN |
---|---|---|---|
1 | 1 | 1 | 1.0 |
2 | 2 | 3 | 1.5 |
3 | 3 | 6 | 2.0 |
4 | 4 | 10 | 2.5 |
6 | 1 | 1 | 1.0 |
但请注意。如果您的目标是直接从您的数据构建您的参数,而不是在函数调用中对它们进行硬编码,您很可能 运行 进入这个问题:
Create or replace View V_array_calcs_input as
Select parse_json()::array arg_list
from (values ('[[1],[1,2],[1,2,3],[1,2,3,4],["A","B"], ["A",1]'));
Select *
from V_array_calcs_input,
table(array_calcs(arg_list));
SQL编译错误:无法计算不支持的子查询类型
存储过程或 JavaScript UDF/UDTF 可能是解决此问题的更好选择,如果您可以在其中任何一个中构建所需的功能逻辑。