sql - 连接类型(内、左)和数据类型转换影响查询计划和操作顺序
问题描述
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
应该保证其参数的评估顺序。
推荐阅读
- python - python pytest occasionally fails with OSError: reading from stdin while output is captured
- dart - 这个 loginRequired(f)() 是在 dart 中处理登录所需功能的方法吗?
- angular - Angular 2 组件 - 使用相同的选择器多次出现
- python - 从包含新操作的python中创建的pb图在c ++中创建图
- random-forest - Time Weighted Samples when using Random Forest
- asp.net-web-api - 我不能说我的 .net 核心项目中缺少什么……我的 Intellisense 不能正常工作还是什么原因?
- python - Update a table when other tables changed in Django ORM
- php - How to properly format an array?
- python - Speed up date columns conversion (pandas) from string to datetime
- javascript - Create a immutable copy of a property