无法在 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 中评估不受支持的子查询类型

“无法识别数值''” - 哪一列?

go工具库分析——go-snowflake

无法将数据从 Snowflake 复制到 Azure Blob

Snowflake 中的返回类型“Table”问题

无法使用 Talend 上传到 Snowflake 阶段,NoSuchMethodError