首先解释一下标题,如SELECT * FROM user WHERE 1<age<4,这句话能否执行?能执行的话会得到什么结果?
且看这样一张表
id | name | age |
---|---|---|
1 | 张三 | 6 |
2 | 李四 | 7 |
3 | 王五 | 8 |
4 | 赵六 | 9 |
当你想要筛选出1-4岁之间(不包含)的年龄的人,可能会写出如下Sql语句:
SELECT * FROM user WHERE age>1 AND age<4
也有可能一时糊涂写出以下Sql语句:
SELECT * FROM user WHERE 1<age<4
会得到以下结果
id | name | age |
---|---|---|
1 | 张三 | 6 |
2 | 李四 | 7 |
3 | 王五 | 8 |
4 | 赵六 | 9 |
返回的结果明显不是我们想要的,居然将整张表查了出来。
有基础的人都知道,如果需要比较两次,中间需要使用AND连接,直接比较两次是错误的语法。
其实在MySql中这样的语法并不错误,之所以得到这样结果,是因为这是理所当然的(不然还能得到什么结果?)。
首先将1<age<4拆分成两部分,一部分是"1<age",另一部分是"(1<age)的结果再<4"。
由于这张表里面所有的age都比1大,所以1<age的结果肯定都为true,true就是1(false也就是0)。
之后再使用这个1,去运算"(1<age)的结果再<4",也就是"1<4",这个结果明显也是1(true)。
既然where的条件的结果都是true,那Sql语句的执行结果自然就是所有的行了。
试着将Sql语句改成
SELECT * FROM USER WHERE 1<age!=1
这样返回的行数就是0了,因为"1<age"的结果为1(true),"1!=1"的结果为0(false)。
再改成:
SELECT * FROM USER WHERE 6<age=1
返回结果为:
id | name | age |
---|---|---|
2 | 李四 | 7 |
3 | 王五 | 8 |
4 | 赵六 | 9 |
age为6的不见了,因为按照where条件,6<6结果为0(false),0=1的结果为0(false),所以这一行理所应当是不符合条件的,而其它行由于都大于6,所以都符合条件。
最后说一下,这样的写法虽然可行,但是新手容易混淆,实在要使用可以加括号来分割,增加易读性。