On 2018/08/19 8:58 AM, 麦轲数据管家 wrote:
create table t1(c int);
insert into t1 values (1),(2),(3);
select * from t1 where c>'' ;   --get nothing(empty result)
select * from t1 where c<'';   --get result set:1,2,3


create table t2(c char);
insert into t2 values (1),(2),(3);
select * from t2 where c>'';    --get correct result set: 1,2,3

the only difference of t1 and t2 is the column data type: int vs char

And what an amazingly important difference that is!

In the first instance, you tell the schema you wish to store values in column c which you would like to be treated as INTEGERs. Not only do you ASK it to be treated as integer, but you then go ahead and INSERT them as integers (without quotes).

Then later, you try to compare these integer values against strings, and an Integer and strings are not compatible and will fail in any strongly typed language, and in a duck-typing system like SQLite, there are usually rules defined for when an incompatible type comparison happens. In the case where one operand is is INT and one is TEXT (like in your first example), then SQLite uses Numeric affinity for the TEXT side USUALLY, but since in this case the empty string ('') doesn't compute to anything useful in Numeric terms, that conversion is moot.  [Should { '' = '0' } return true?]

In the second example you ask it to store the values as strings (characters) and then continue to compare them with other strings, something that is definitely allowed, easily understood by ANY type system and as expected, yield correct results.

A simple cast would fix your problem:

create table t1(c int);
insert into t1 values (1),(2),(3);
select * from t1 where cast(c AS text) > '' ;   --gets correct results

Or, using a function that implicitly casts, like this:

create table t1(c int);
insert into t1 values (1),(2),(3);
select * from t1 where trim(c) > '' ;   --gets correct results


I hope that answers that, but let me offer some reasoning as to why it is not 
only needed, but also useful/efficient to choose the right types/affinities:

Equality is a straight forward concept in set theory, but it's weird thing in reality. 
For example, if I have two of the exact same model Toyotas, we could say they are equal. 
But what if one is green and one red? - Some would say they are exactly the same cars if 
you consider their "carness", and other would point out that they are not 
exactly the same because the colour is different. Similarly, we can ask if two values are 
the same, but they have different types, are they really equal? Arguments can be made for 
both answers and the mentioned rules typically aim to choose the best in any situation. 
To further illustrate the problem faced by SQLite (and duck typing systems in general):  
Would you say the value 1.23E+5 should be higher or lower than the text '1.23E10', 
'1.23E' or '12345'? (At which point do we choose one compare method over the other?)

In human terms it feels "easy" to check the entire text for "numberness", but I 
don't want my comparator to dwell on numbernicity for thousands of CPU cycles on every comparison 
before it decides. This is why we have types and affinities to express how we want it to interpret 
values. (Apologies for inventing lots of words there). If SQLite knows before-hand what the operand 
affinities are, it spends no time figuring out which rule to apply, or more importantly, converting 
values to fit the decided-upon rule.

SQLite makes a good effort to compare apples with apples, and does so rather efficiently, 
but the less it has to "figure out" on the fly, the better.

Here are some simple examples to show the (sometimes less intuitive) workings 
when comparing things in SQLite:


select 5 = '5' ;
  -- -------
  --    0


select CAST('5' AS INT) = '5' ;
  -- ------------
  --       1


select CAST(5 AS TEXT) = '5' ;
  -- ------------
  --       1


select 534545 < ' 1' ;
  -- ------------
  --       1



Cheers,
Ryan


_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to