【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】
【资源配置】
【附件:截图/日志/监控】
上面是0 下面是1
【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】
【资源配置】
【附件:截图/日志/监控】
请标注说明是哪个版本的集群
还有贴一下完整的文本内容,方便我们帮你验证和测试
这两个条件似乎不是等价的
示例:
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)
这种缩写我是第一次见 用正常语法吧
id<=2<=id1
的计算顺序是先计算 id<=2
,然后将结果与 id1
进行比较。这样会导致将所有满足 id<=2
的行都返回,而不管 id1
的值是多少
没见过id<=2<=id1语法,返回3和4感觉怪怪的3<=2<=4
先计算 id<=2
,然 然后将结果与 id1
进行比较。
这个结果是什么,比较类结果应该是true和false吧
我是放在比较的,结果第一个是false ,第二个true
mysql5.7
测试结果和这个一致。
这语法结果有点怪,感觉很容易误导
你这写法真是让人一言难尽,采用正常写法不好吗?尽量把列字段放到前面,比如C.TIMESHEETTIMEFROM<=‘19:00’ and C.TIMESHEETTIMETO >= ‘19:00’
发下执行计划
额。。。还可以这样写么?第一次见这种语法。
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)
感觉是解析算法变了
不确定是什么场景会用到这种写法。对于 where id<=2<=id1,内部执行过程,其实是 where (id<=2)<=id1。也就是:
1.先执行判断id<=2得到结果0或1
2.再用上一步的结果值0或1,去和 id1 列进行比较。得到最终的输出值。
结论:除非是业务特殊需要,而且很确定自己的业务场景就需要这种非常规 SQL 写法、不担心产生歧义,才去使用它;否则,不建议使用该写法。
写法第一次见到过,还是用标准语法吧。
很明显,两种写法真实计算方法不一样,结果不一样正常
这个解释很清晰。