问题
I've got a query where I'm comparing values with <
and >
. The database is old and was poorly designed so unfortunately we have columns that should be INT
but instead are VARCHAR
.
The column is called PayCode
and is of type VARCHAR(50)
.
If I have a WHERE
clause like this:
WHERE PayCode > 200
then when I look at the execution plan there are warnings about implicit conversion and cardinality estimates.
What I don't understand is why the below gets rid of those warnings:
WHERE PayCode > '200'
I understand that I've made them both VARCHAR
, but the logic actually seems to work (it's not doing an alphabetical comparison) which would imply that it's converting both to integers anyway. Would that not be an implicit conversion?
Oddly, the below still causes cardinality estimate warnings:
WHERE CAST(PayCode AS INT) > 200
So how come I can use greater than/less than with VARCHAR
representations of integers and have both the logic work and no implicit conversion or cardinality issues?
回答1:
So how come I can use greater than/less than with VARCHAR representations of integers and have both the logic work.
You can't. 3 < 200,
but '3' > '200'
. When operating on VARCHAR the comparison operators use an alpha-numeric sort order defined by the COLLATION.
EG:
drop table if exists #t
create table #t(PayCode varchar(20))
insert into #t(PayCode) values ('3')
select *
from #t
WHERE PayCode > '200'
回答2:
Data type precedence defines the rules:
When an operator combines expressions of different data types, the data type with the lower precedence is first converted to the data type with the higher precedence. If the conversion isn't a supported implicit conversion, an error is returned. For an operator combining operand expressions having the same data type, the result of the operation has that data type.
In your case there is VARCHAR
vs INT
so:
WHERE PayCode > 200
-- implicit conversion of PayCode to INT
WHERE PayCode > '200' (VARCHAR vs VARCHAR)
-- no need for implicit conversion
-- beware that lexicographical order may not always be the same as number order
-- (leading 0, - sign, thousand separator)
来源:https://stackoverflow.com/questions/58357450/how-does-implicit-conversion-work-with-comparisons-of-varchar-representati