无法在 Snowflake 中使用混合数据类型的字段内连接两个简单的 CTE
Posted
技术标签:
【中文标题】无法在 Snowflake 中使用混合数据类型的字段内连接两个简单的 CTE【英文标题】:Cannot inner join two simple CTEs on a field with mixed data types in Snowflake 【发布时间】:2021-03-10 12:37:09 【问题描述】:问题
我不能 inner join
Snowflake 中的两个简单 CTE。简洁的错误消息没有显示方式。
我的查询有什么问题?加分:为什么我的查询在 SQL Server 中有效,但在 Snowflake 中无效?
背景
我是雪花的新手。我习惯了 SQL Server。我想查询 Snowflake 中 2 个表的 inner join
。表 1 和表 2 显示了我想要加入的表。表3是我想要的结果。
我想使用简单的where
子句在 CTE 中删除第一个表的一些行。当我运行我的查询(见下文)时,我收到一条简洁的错误消息:
Numeric value 'HAHA! IM CAUSING TROUBLE' is not recognized
但我认为我在第一个 CTE 中“删除”了这个值。
我的查询有什么问题?加分:为什么我的查询在 SQL Server 中有效,但在 Snowflake 中无效?
表 1:字段历史
id | date | field_id | field_value |
---|---|---|---|
1 | 2020-01-01 | unwanted | HAHA! IM CAUSING TROUBLE |
2 | 2020-01-02 | thing | 100 |
3 | 2020-01-03 | thing | 101 |
4 | 2020-01-04 | thing | 102 |
5 | 2020-01-05 | thing | null |
6 | 2020-01-06 | thing | 103 |
表 2:我想加入的事情
thing_id | thing_start_date | thing_end_date | something_i_care_about |
---|---|---|---|
100 | 2020-01-01 | 2020-02-01 | secret alien intelligence |
101 | 2020-02-01 | 2020-03-01 | blueprints for shark lazers |
102 | 2020-03-01 | 2020-04-01 | non-YA biz-NAZZ |
103 | 2020-04-01 | 2020-05-01 | who will win bachelorette |
表 3:我的梦想决赛桌
id | date | thing_id | thing_start_date | thing_end_date | something_i_care_about |
---|---|---|---|---|---|
2 | 2020-01-02 | 100 | 2020-01-01 | 2020-02-01 | secret alien intelligence |
3 | 2020-01-03 | 101 | 2020-02-01 | 2020-03-01 | blueprints for time machine |
4 | 2020-01-04 | 102 | 2020-03-01 | 2020-04-01 | non-YA biz-NAZZ |
6 | 2020-01-06 | 103 | 2020-04-01 | 2020-05-01 | who will win bachelorette |
我尝试过的
with field_history as ( -- CTE with simple where clause
select
id
, date
, to_number(field_value, 38, 0) as thing_id -- SQL Server equivalent would be cast() or convert()
from db.schema.history
where field_id = 'thing' and field_value is not null
),
things_i_want as (
select
*
from db.schema.things
),
final as (
select
field_history.id
, field_history.date
, things.*
from field_history
inner join things_i_want on field_history.thing_id = things_i_want.thing_id
)
select * from final
超级有用的错误消息阻止我做梦
Numeric value 'HAHA! IM CAUSING TROUBLE' is not recognized
【问题讨论】:
似乎“to_number”在两个系统上的无效字符串上表现不同。尝试改用docs.snowflake.com/en/sql-reference/functions/…。 @RomanHocke 哇。所有这些。而且我只是使用了错误的转换功能。 ????♂️我们可以删除我们现在尴尬的帖子吗?谢谢你。这就是我所缺少的。 【参考方案1】:数值'哈哈! IM CAUSING TROUBLE' 无法识别
您的错误消息是类型转换问题,似乎在这里:
to_number(field_value, 38, 0) as thing_id
您可能认为where
子句过滤掉了错误的值。然而,SQL 引擎可以——并且确实——重新安排操作。我建议使用case
表达式来处理这个问题:
(case when field_value regexp '^[0-9]+$'
then to_number(field_value, 38, 0)
end) as thing_id
case
表达式保证按顺序运行表达式。
上述想法(但不是regexp
部分)适用于 SQL Server 和 Snowflake。
仅在 Snowflake 中,您可以使用 try_
函数:
try_to_number(field_value, 38, 0) as thing_id
【讨论】:
非常正确的 Gordon:Snowflake 确实在变量数据(又名 json)的 WHERE 子句之前运行 SELECT 转换,因此如果您的列具有混合类型,则必须使用TRY_x
形式脚轮。有时 CASE 和 COALESCE 可以帮助你,但是当它重新排序变换时,它会神奇地再次爆炸。所以规则是数据类型总是尽量安全。
@SimeonPilgrim 。 . .具有讽刺意味的是,SQL Server 还会将一堆转换推送到 DAG 中的读取节点——通常会导致这种类型的转换错误。我很惊讶代码在 SQL Server 中工作。【参考方案2】:
这是一个简单的错误。您正在尝试转换字符串 'HAHA!我给 Number 造成了麻烦'。即使您将其删除,您也可能会因为 Field_History 表中同一列中的 null 而出现错误。您需要在查询中处理它。不确定您在 SQL Server 中编写的具体查询是什么,因此无法说明它为什么有效。
【讨论】:
以上是关于无法在 Snowflake 中使用混合数据类型的字段内连接两个简单的 CTE的主要内容,如果未能解决你的问题,请参考以下文章
SQL 编译错误:无法在 Snowflake 中评估不受支持的子查询类型