为何Snowflake会返回WHERE子句判定为FALSE的记录?
问题:Snowflake中GENERATOR查询的WHERE子句未生效的原因?
我在Snowflake中执行了以下使用GENERATOR(无需依赖表)的查询:
SELECT DATEADD(day, SEQ4() * 7, '2022-11-13'::DATE) AS date_column, DATEADD(week, -98, CURRENT_DATE) as anchor_date, current_date, DATEADD(day, SEQ4() * 7, '2022-11-13'::DATE) BETWEEN DATEADD(week, -98, CURRENT_DATE) AND CURRENT_DATE as truthy FROM TABLE(GENERATOR(ROWCOUNT => 5000)) WHERE DATEADD(day, SEQ4() * 7, '2022-11-13'::DATE) BETWEEN DATEADD(week, -98, CURRENT_DATE) AND CURRENT_DATE order by date_column
查询返回的部分记录如下:
| date_column | anchor_date | current_date | truthy |
|---|---|---|---|
| 2022-11-13 | 2022-12-13 | 2024-10-29 | FALSE |
| 2022-11-20 | 2022-12-13 | 2024-10-29 | FALSE |
| 2022-11-27 | 2022-12-13 | 2024-10-29 | FALSE |
| 2022-12-04 | 2022-12-13 | 2024-10-29 | FALSE |
| 2022-12-11 | 2022-12-13 | 2024-10-29 | FALSE |
| 2022-12-18 | 2022-12-13 | 2024-10-29 | TRUE |
| 2022-12-25 | 2022-12-13 | 2024-10-29 | TRUE |
| 2023-01-01 | 2022-12-13 | 2024-10-29 | TRUE |
| 2023-01-08 | 2022-12-13 | 2024-10-29 | TRUE |
| 2023-01-15 | 2022-12-13 | 2024-10-29 | TRUE |
显然前5条记录的WHERE子句判定结果为FALSE,但查询仍返回了这些记录。我猜测这可能和无表/GENERATOR的设置有关,但不确定原因。我知道可以通过嵌套查询SELECT * FROM () where truthy;解决问题,但更想理解当前查询不生效的背后原因。
原因分析
核心问题出在SEQ4()函数的执行特性上:
- SEQ4()是Snowflake的易失性函数,它在查询的不同执行阶段会生成独立的序列值,而非固定的同一组序列。
- 当执行WHERE子句时,SEQ4()生成一组序列值,用来筛选出符合日期范围的行;但进入SELECT子句阶段时,SEQ4()会重新生成另一组序列值,这就导致SELECT中计算出的
date_column和WHERE子句里用于过滤的date_column并非同一组值。 - 直观来说:WHERE阶段用SEQ4()筛选出了符合条件的行,但SELECT阶段重新计算SEQ4()时,生成的序列对应了更早的、本该被过滤的日期,最终结果里就出现了
truthy为FALSE的记录。
用嵌套查询解决的原理也很简单:子查询会先完成所有列的计算(包括date_column和truthy),生成固定的结果集,外层WHERE直接使用这些预计算好的值,不会重复调用SEQ4(),自然避免了序列值不一致的问题。
内容的提问来源于stack exchange,提问作者Chipmonkey
相关产品推荐
相关产品推荐

