我喜欢 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/