在雪花中设置变量

Setting variables in snowflake

我想在 CTE table 之前和 CTE table 之后定义变量,因为一些变量取决于 CTE table 的结果。例如

SET(K,B) = (5,2);

with my_data(Key,Index,Value) as (
    -- data table as cte
    select * from values
        (1, 3, 10),
        (1, 5, 18),
        (1, 14, 4),
        (2, 2, 11),
        (2, 13, 24),
        (2, 29, 40)
)

SELECT VALUE + $K
FROM my_data 

这个例子完美运行。但是这段代码:

SET(K,B) = (5,2);

with my_data(Key,Index,Value)   as (
    -- data table as cte
    select * from values
        (1, 3, 10 ),
        (1, 5, 18 ),
        (1, 14, 4 ),
        (2, 2, 11 ),
        (2, 13, 24),
        (2, 29, 40)
)

SET AVG_VAL = (SELECT AVG(VALUE) FROM my_data);

SELECT VALUE + $AVG_VAL
FROM my_data

不是因为雪花给我这个错误

"SQL compilation error: syntax error line 34 at position 0 unexpected 'SET'."

我是否应该创建一个临时 table 来存储此查询 (SELECT AVG(VALUE) FROM my_data) 的结果,然后 include/use 这个临时 table 用于将来的查询而不是变量?

这可以像 -

那样完成
select * from d2;
+-----+-----+
| ID1 | ID2 |
|-----+-----|
|   1 |   2 |
| 100 |   2 |
|   3 |   4 |
| 300 |   4 |
+-----+-----+

设置变量-

set (var1) = (select sum(id2) from d2);
+----------------------------------+
| status                           |
|----------------------------------|
| Statement executed successfully. |
+----------------------------------+

使用变量-

select id1+$var1 from d2;
+-----------+
| ID1+$VAR1 |
|-----------|
|        13 |
|       112 |
|        15 |
|       312 |
+-----------+

您的“CTE”不是一个独立的“事物”,它仅存在于 SELECT.

的上下文中

因此

WITH cte_x AS (...)
SELECT * FROM cte_x

是一个 SELECT 附加了 CTE。

因此对于您的变量赋值,CTE 必须“在”paren 的

   with my_data(Key,Index,Value) as (
        select * from values
            (1, 3, 10 ),
            (1, 5, 18 ),
            (1, 14, 4 ),
            (2, 2, 11 ),
            (2, 13, 24),
            (2, 29, 40)
    )
    SELECT AVG(VALUE) FROM my_data;
AVG(VALUE)
17.833333

鉴于它是 SQL 的离散块,可以将其捕获到变量中:

set AVG_VAL = (
    with my_data(Key,Index,Value) as (
        select * from values
            (1, 3, 10 ),
            (1, 5, 18 ),
            (1, 14, 4 ),
            (2, 2, 11 ),
            (2, 13, 24),
            (2, 29, 40)
    )
    SELECT AVG(VALUE) FROM my_data
);
status
Statement executed successfully.

现在我们可以使用该值:

select $AVG_VAL * 2;
$AVG_VAL * 2
35.666666

但是下一个查询:

SELECT VALUE + $AVG_VAL
FROM my_data

002003 (42S02): SQL compilation error:

Object 'MY_DATA' does not exist or not authorized.

没有名为 my_data 的 CTE,因此需要插入:

with my_data(Key,Index,Value) as (
        select * from values
            (1, 3, 10 ),
            (1, 5, 18 ),
            (1, 14, 4 ),
            (2, 2, 11 ),
            (2, 13, 24),
            (2, 29, 40)
    )
SELECT VALUE + $AVG_VAL
FROM my_data

如果你想要一个可以“使用两次”的 table,你将需要一个实际的 table,此时我建议使用一个临时的 table,这样它只有上下文在这个 session.

Pankaj 回答的性质(通过永久或临时的以太币 table)

另一种方法是简单地使用 windowed AVG 函数:

with my_data(Key,Index,Value) as (
    -- data table as cte
    select * from values
        (1, 3, 10),
        (1, 5, 18),
        (1, 14, 4),
        (2, 2, 11),
        (2, 13, 24),
        (2, 29, 40)
)
SELECT VALUE, AVG(VALUE) OVER(),
      VALUE + AVG(VALUE) OVER()
FROM my_data;

输出:

OVER() 表示 window 用于计算所有行的平均跨度。