Предложение WHERE для альфа-столбца, содержащего целые числа, не выполняется в целочисленном сравнении - PullRequest
1 голос
/ 20 июня 2019

Я не могу понять, почему сравнение не удается в этом примере кода:

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

Я понимаю, что это не с включенным альфа-значением, так как преобразование в 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 ]

3 голосов
/ 20 июня 2019

Оптимизатор запросов может выполнять любую оптимизацию, например предикат 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

0 голосов
/ 27 июня 2019

Я проверяю и обнаруживаю, что эти запросы также работают:

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

Согласно документу, nvarchar можно преобразовать в int с помощью неявных преобразований .enter image description here

Вы сравниваете тип данных nvarchar с типом данных int, сервер SQL преобразует все значения столбца "a" в int.Но не все значения можно преобразовать:

enter image description here

Но если преобразовать int в nvarchar, запрос будет работать.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...