包含整数的alpha列上的WHERE子句在整数比较中失败

时间:2019-06-20 13:50:41

标签: sql tsql azure-sql-database

在此示例代码中,我看不到为什么比较失败:

create table #a(a nvarchar(10))
insert #a values( 1 )
insert #a values( 2 )
insert #a values( 3 )
insert #a values('A')
select * from (select * from #a where a not like 'A%') b where a < 2
drop table #a

我了解到它失败,并包含alpha值,因为转换为int失败,但是当我将其从候选行集b中明确排除时,为什么仍尝试转换第四行?如果我通过将b编写为表格将其分成两部分,则可以正常工作。也就是说,这是

create table #a(a nvarchar(10))
insert #a values( 1 )
insert #a values( 2 )
insert #a values( 3 )
insert #a values('A')
select * into #b from (select * from #a where a not like 'A%') b
select * from #b where a < 2
drop table #a
drop table #b

...有效。我想念什么?这是Azure SQL。

2 个答案:

答案 0 :(得分:3)

查询优化器可以自由执行predicate pushdown之类的任何优化:

select * from (select * from #a where a not like 'A%') b where a < 2
=>
select * from #a where a not like 'A%' and a < 2;
-- the order of execution is not guaranteed so it tries comparison 'A' < 2
-- VARCHAR vs INT, INT has higher data type precedence, implicit conversion to INT

为了避免像第二个示例那样必须实现子查询。

不幸的是,SQL Server尚不支持实体化提示:https://feedback.azure.com/forums/908035-sql-server/suggestions/32642629-t-sql-common-table-expression-materialize-option

答案 1 :(得分:0)

我测试并发现这些查询也有效:

create table #a(a nvarchar(10))
insert #a values( 1 )
insert #a values( 2 )
insert #a values( 3 )
insert #a values('A')
insert #a values('B')
--query1
select * from (select * from #a where a not like 'A%') b where a < '2'

--query2
select * from #a where a < '2' and a not like 'A%'

--query3
select * from #a where a < '2'
drop table #a

根据文档,implicit conversions可以将nvarchar转换为intenter image description here

nvarchar数据类型与int数据类型进行比较,SQL Server会将所有“ a”列值转换为int。但并非所有值都可以转换:

enter image description here

但是,如果将int转换为nvarchar,则查询有效。

希望这会有所帮助。