联接类型(内部、左侧)和数据类型转换会影响查询计划和操作顺序


create or replace table test.bugs.table_one as (
select *, random(1337) as cost
from (
values 
('', '2010-01-01', 'one')
, ('10', '2010-01-01', 'two')
, ('11', '2010-01-01', 'three')
, ('12', '2010-01-01', 'four')
)
);
create or replace table test.bugs.table_two as (
select *, random(1337) as budget
from (
values 
(9, '2010-01-01', 'one')
, (10, '2010-01-01', 'two')
)
);
with 
t1 as (
select 
column1::int as column1
, column2
, column3
, cost
from table_one
where column1 !=''
),
t2 as (
select
column1
, column2
, column3
, budget
from table_two
)
select *
from t1
inner join t2
on t1.column1 = t2.column1
and t1.column2 = t2.column2
and t1.column3 = t2.column3;

回报:3 rows

将联接类型更改为INNER会导致错误:Numeric value '' is not recognized。我最终没有使用::int而是try_to_number()函数,但需要一些反复试验才能弄清楚(上面的查询被简化,我的查询更复杂(。

这是一个错误,还是我在做一些奇怪的事情?

数据库不保证表达式的计算顺序。 在某些数据库中,您的代码始终有效。 在其他情况下,它有时可能有效,有时可能失败。

这是一个错误吗? 我认为这是一个错误,但显然一些数据库供应商没有。 您已经找到了解决方法。 另一种方法是case表达式:

select (case when column1 regexp '^[0-9]+$' then column1::int end)

这应该有效,因为case应该保证其参数的评估顺序。

当连接时,因为内部连接在连接之前或之后完成的事情是相等的。所以像演员这样的东西可以被吊起来。

WHERE子句应该在 t1 CTE 的 SELECT 部分之前进行评估。

我刚刚通过错误提交代码重新测试,现在损坏的情况可以工作,但工作案例(具有正确的TRY_TO_NUMBER失败(。

我有像你这样的查询,然后一旦在外部运行了额外的选择层并对结果进行聚合,铸件就会被提升回错误状态。

但是,是的,这是一个错误,所以我会报告它。

最新更新