【问题标题】:Use dynamic value in snowflake time travel sql在雪花时间旅行sql中使用动态值
【发布时间】: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


【解决方案1】:

当我运行类似的东西时,我得到了这个错误:

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());

【讨论】:

  • 谢谢。实际上,我想根据 my_table_2 中的特定时间戳值在 my_table1 上创建一个视图。在这种情况下,变量选项将不起作用
  • 嗯。我想不出一种在视图中执行此操作的方法,但是 UDF 可能可以为您提供所需的内容。不过,我必须更多地了解您想要的输入和输出。 docs.snowflake.net/manuals/sql-reference/…
  • 编辑了与您的用例相关的 UDF 示例。今晚我无法为此设置一个完整的测试环境,所以你肯定不得不摆弄它。
【解决方案2】:

时间旅行只能用一个常数来指定,这使得我无法参数化(目前)。

执行此操作的唯一方法是通过存储过程,您可以在其中以文本形式提供查询。
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);

【讨论】:

    【解决方案3】:

    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());

    【讨论】:

    • 当然,但为了自动化任何非恒定时间旅行,您必须[暂时]使用存储过程。
    • 顺便说一句,很高兴看到可以从表达式中设置 SQL 变量。这是全新的,还是我错过了任何公告?文档没有表达式示例...
    猜你喜欢
    • 2022-11-15
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 2022-01-05
    相关资源
    最近更新 更多