sql - Snowflake中的语句绑定(bind)/执行顺序

标签 sql snowflake-cloud-data-platform

我喜欢 Snowflake 的原因之一是,它对于子句何时可用于其他子句没有那么严格。例如以下内容:

WITH tbl (name, age) as (
    SELECT * FROM values ('david',10), ('tom',20)
)
select
    name,
    age,
    year(current_timestamp())-age as birthyear
from
    tbl
where
    birthyear > 2010

我可以在 WHERE 子句中使用 birthyear。这将与 SQL Server 之类的东西结合起来,其中绑定(bind)要严格得多,例如 here 。是否有关于 Snowflake 中绑定(bind)顺序的任何文档,或者通常是“松散”的,解析器会为您解决问题?

或者,与MySQL5.7中相同:

select
    name,
    age,
    year(now())-age as birthyear
from
    (select 'tom' name, 20 age union select 'david', 10) tbl
where birthyear > 2010

Unknown column 'birthyear' in 'where clause'

最佳答案

免责声明:这是我理解此功能的方式,可能不完整


由于出生年份未知,像下面这样的构造将会失败。

select
    name,
    age,
    year(current_timestamp())-age as birthyear
from  tbl
where birthyear > 2010;

通常我们使用子查询或简单地复制表达式:

select *
from ( select
          name,
          age,
          year(current_timestamp())-age as birthyear
      from  tbl) s
where birthyear > 2010;

select
    name,
    age,
    year(current_timestamp())-age as birthyear
from  tbl
where year(current_timestamp())-age > 2010;

还有另一种方法可以使用 LATERAL JOIN/CROSS APPLY 来实现它:

select
    name,
    age,
    s.birthyear
from  tbl
,LATERAL(SELECT year(current_timestamp())-age as birthyear) s
where s.birthyear > 2010;

我们可以更进一步,在同一级别使用两次别名:

select
    name,
    age,
    year(current_timestamp())-age as birthyear,
    CASE birthyear > 2000 THEN 'XXI'ELSE 'XX' END AS century
from  tbl
where birthyear > 2010;

这相当于链式横向连接:

select
        name,
        age,
        s.birthyear,
        s2.century
 from  tbl
 ,LATERAL (SELECT year(current_timestamp())-age as birthyear) s
 ,LATERAL (SELECT CASE WHEN s.birthyear > 2000 THEN 'XXI'ELSE 'XX' END AS century) s2
 where s.birthyear > 2010;

<强> db<>fiddle demo

Snowflake 的版本是一种“LATERAL JOIN 的内联版本”,非常简洁。


相关:PostgreSQL: using a calculated column in the same query

值得一提的是:此语法不允许嵌套窗口函数 Using nested window function in Snowflake或者在 WHERE 中使用它们:

SELECT *, ROW_NUMBER() OVER(ORDER BY col1) AS rn
FROM t
WHERE rn > 10;

=>
SELECT *, ROW_NUMBER() OVER(ORDER BY col1) AS rn
FROM t
QUALIFY rn > 10;

关于sql - Snowflake中的语句绑定(bind)/执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69715149/

相关文章:

sql - 永远循环的 T-SQL 中的 While 子句

sql - 带有 "or"运算符的 DB2 SQL 正则表达式

sql - 为什么存储过程不能从另一个数据库读取表(我一定是错误地使用了 GRANT 和 DENY)

雪花中的Javascript函数将当前日期附加到表名

sql - SQL 中的连续转换

sql - 如何在 SQL 中对字符串值或数组进行排序

php - sprintf() 与 mysql_query()

sql - 我怎样才能让这条SQL更新语句更有效率呢?

sql - 在 Snowflake SQL 中获取不同的层次结构级别和路径

snowflake-cloud-data-platform - 授予雪花角色创建仓库的权限,但不起作用