同样语句加不加and结果不一样

【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】
【资源配置】
【附件:截图/日志/监控】


上面是0 下面是1

请标注说明是哪个版本的集群
还有贴一下完整的文本内容,方便我们帮你验证和测试

1 个赞

这两个条件似乎不是等价的

示例:
mysql> select * from t1;
±-----±-----+
| id | id1 |
±-----±-----+
| 1 | 2 |
| 2 | 3 |
| 3 | 4 |
±-----±-----+
3 rows in set (0.00 sec)

mysql> select * from t1 where id<=2 and id1>=2;
±-----±-----+
| id | id1 |
±-----±-----+
| 1 | 2 |
| 2 | 3 |
±-----±-----+
2 rows in set (0.00 sec)

mysql> select * from t1 where id<=2<=id1;
±-----±-----+
| id | id1 |
±-----±-----+
| 1 | 2 |
| 2 | 3 |
| 3 | 4 |
±-----±-----+
3 rows in set (0.00 sec)

1 个赞

这种缩写我是第一次见 用正常语法吧

1 个赞

id<=2<=id1 的计算顺序是先计算 id<=2 ,然后将结果与 id1 进行比较。这样会导致将所有满足 id<=2 的行都返回,而不管 id1 的值是多少

1 个赞

没见过id<=2<=id1语法,返回3和4感觉怪怪的3<=2<=4


可是这个id不小于2啊

先计算 id<=2 ,然 然后将结果与 id1 进行比较。

这个结果是什么,比较类结果应该是true和false吧

1 个赞

我是放在比较的,结果第一个是false ,第二个true

mysql5.7

测试结果和这个一致。

这语法结果有点怪,感觉很容易误导

你这写法真是让人一言难尽,采用正常写法不好吗?尽量把列字段放到前面,比如C.TIMESHEETTIMEFROM<=‘19:00’ and C.TIMESHEETTIMETO >= ‘19:00’

1 个赞

发下执行计划

额。。。还可以这样写么?第一次见这种语法。

select * from t1 where id1<=1<=id2这个SQL是先计算的id1<=1得到逻辑值0或者1,再和id2对比:
le(le(test.t1.id1, 1), test.t1.id2)
不建议楼主使用这种非主流SQL。

测试过程如下:

my:root@192.168.3.22:4000=> create table t1(id1 int,id2 int);
CREATE TABLE
my:root@192.168.3.22:4000=> insert into t1 values(1,1);
INSERT 1
my:root@192.168.3.22:4000=> insert into t1 values(2,1);
INSERT 1
my:root@192.168.3.22:4000=> select * from t1 where id1<=1<=id2;
 id1 | id2 
-----+-----
   1 |   1 
   2 |   1 
(2 rows)

my:root@192.168.3.22:4000=> select * from t1 where id1<=1 and 1<=id2;
 id1 | id2 
-----+-----
   1 |   1 
(1 row)

my:root@192.168.3.22:4000=> explain 
my:root@192.168.3.22:4000-> select * from t1 where id1<=1<=id2;
          id           | estRows  |   task    | access object |            operator info            
-----------------------+----------+-----------+---------------+-------------------------------------
 TableReader_7         | 8000.00  | root      |               | data:Selection_6 
 └─Selection_6       | 8000.00  | cop[tikv] |               | le(le(test.t1.id1, 1), test.t1.id2) 
   └─TableFullScan_5 | 10000.00 | cop[tikv] | table:t1      | keep order:false, stats:pseudo 
(3 rows)

my:root@192.168.3.22:4000=> explain 
my:root@192.168.3.22:4000-> select * from t1 where id1<=1 and 1<=id2;
          id           | estRows |   task    | access object |             operator info              
-----------------------+---------+-----------+---------------+----------------------------------------
 TableReader_7         | 0.22    | root      |               | data:Selection_6 
 └─Selection_6       | 0.22    | cop[tikv] |               | le(1, test.t1.id2), le(test.t1.id1, 1) 
   └─TableFullScan_5 | 2.00    | cop[tikv] | table:t1      | keep order:false, stats:pseudo 
(3 rows)
3 个赞

感觉是解析算法变了

不确定是什么场景会用到这种写法。对于 where id<=2<=id1,内部执行过程,其实是 where (id<=2)<=id1。也就是:
1.先执行判断id<=2得到结果0或1

  • 0 表示 false,id 列大于 2 的值就会得到这个结果,比如 id 列是 3 ,那么 3<=2 得到的结果就是 0 了。
  • 1 表示 true,id 列小于等于 2 的值就会得到这个结果,比如 id 列是 1或者2 ,那么得到的结果就是 1 了。

2.再用上一步的结果值0或1,去和 id1 列进行比较。得到最终的输出值。

结论:除非是业务特殊需要,而且很确定自己的业务场景就需要这种非常规 SQL 写法、不担心产生歧义,才去使用它;否则,不建议使用该写法。

1 个赞

写法第一次见到过,还是用标准语法吧。

很明显,两种写法真实计算方法不一样,结果不一样正常

这个解释很清晰。