【发布时间】:2019-11-30 23:16:42
【问题描述】:
我想在雪花的时间旅行sql中使用动态值
select * from my_table at (timestamp => (select max(COMPLETION_DATE) from my_table_2):: timestamp)
【问题讨论】:
-
您能否对您所看到的内容进行说明?就像您遇到的任何错误一样。
标签: snowflake-cloud-data-platform
我想在雪花的时间旅行sql中使用动态值
select * from my_table at (timestamp => (select max(COMPLETION_DATE) from my_table_2):: timestamp)
【问题讨论】:
标签: snowflake-cloud-data-platform
当我运行类似的东西时,我得到了这个错误:
SQL compilation error: argument TIMESTAMP to function AT needs to be constant
我相信一个变量可以解决这个问题:
set x = (select max(COMPLETION_DATE)::timestamp from my_table_2);
select * from my_table at (timestamp => $x);
编辑视图
我认为您不能一蹴而就,但您可以使用 UDF 做类似的事情。请参阅此处的文档:https://docs.snowflake.net/manuals/sql-reference/udf-table-functions.html
类似这样的:
create or replace function My_timetravel()
returns table (column1 varchar, column2 numeric(11, 2))
as
$$
set x = (select max(COMPLETION_DATE)::timestamp from my_table_2);
select column1, column2 from my_table at (timestamp => $x);
$$
;
select * from table(My_timetravel());
【讨论】:
时间旅行只能用一个常数来指定,这使得我无法参数化(目前)。
执行此操作的唯一方法是通过存储过程,您可以在其中以文本形式提供查询。
I answered a similar question some days ago 使用此过程:
CREATE OR REPLACE PROCEDURE TIME_TRAVEL(QUERY TEXT, DAYS FLOAT)
RETURNS VARIANT LANGUAGE JAVASCRIPT AS
$$
function run_query(query, offset) {
try {
var sqlText = query.replace('"at"', " AT(OFFSET => " + (offset + 0) + ") ");
return (snowflake.execute({sqlText: sqlText})).next();
}
catch(e) { return false }
}
var days, result = [];
for (days = 0; days < DAYS; days++)
if (run_query(QUERY, -days * 86400)) result.push(days);
return result;
$$;
CALL TIME_TRAVEL('SELECT * FROM TASK_HISTORY "at" WHERE QUERY_ID = ''019024ef-002e-8f71-0000-05e10030a782''', 7);
【讨论】:
Snowflake 中的会话变量可以与查询替换一起使用,并有助于您的时间旅行查询的时间戳子句。目前,UDF 中不支持此功能,因此您需要声明会话变量,然后将其与您的 UDF 一起使用:
SET x = (SELECT current_timestamp());
CREATE OR REPLACE FUNCTION my_timetravel()
RETURNS TABLE (c1 int)
AS
$$
SELECT c1 FROM t1 AT (TIMESTAMP => $x)
$$
;
从表中选择 c1(my_timetravel());
【讨论】: