单表查询 字段与条件的值 数据类型不同 查询出错

【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】5.4
【复现路径】单表查询出错
【遇到的问题:问题现象及影响】

sql 如下:
select * from fac_app_data_table_field_val where table_id = 1969241186793349598 and val0 = 1983480395684134919

查询结果

查询 val0 字段 为 1983480395684134919的记录 但是却将 val0 为 1983480395684134999 的数据查询出来了

业务需要 必须将 val0设置为 varchar类型的

【资源配置】进入到 TiDB Dashboard -集群信息 (Cluster Info) -主机(Hosts) 截图此页面
【附件:截图/日志/监控】

val0为 varchar类型的,条件里没有带单引号啊,带上试试

关联查询的时候 不能 老是用语法转化啊,而且复杂sql 转化还出问题 可以看下我的另一个问题

要尽量避免让数据库做隐式转换,可以看看执行计划

val0值要使用引号引起来避免类型转换

我也发现了 复杂sql隐式转化会出问题 但是我们项目需要这样做,而且已经成型了,有没有什么好的方法能够解决的?

表结构是啥啊,字段对应的数值类型是啥,可以拿出来看看,如果涉及到隐士转换可以用cast解决,你的数值貌似已经接近bigint的最大值,估计会出问题吧

是的,mysql我记得也一样有这个问题,varchar转换bigint会有精度丢失问题,字段类型不能变的话只能改代码了,要么加上引号要么用cast函数

bigint丢精度,以前论坛就有人说,两个不一样的数字判断是否相等返回true
table_id和val0是什么类型

不行直接改表结构把,原来的bigint改成varchar。。。

这个字段只能是字符串的

哪关联的另一个字段是bigint嘛?

CREATE TABLE fac_app_data_table_field_val (
id bigint(20) NOT NULL,
school_id int(11) NOT NULL COMMENT ‘学校ID’,
table_id bigint(20) NOT NULL COMMENT ‘数据表ID’,
batch_code varchar(50) NOT NULL COMMENT ‘提交数据批次号’,
user_id bigint(20) NOT NULL COMMENT ‘归属人ID’,
submit_id bigint(20) NOT NULL COMMENT ‘提交人ID’,
user_type varchar(50) NOT NULL COMMENT ‘归属人角色’,
submit_type varchar(50) NOT NULL COMMENT ‘提交人角色’,
source int(11) NOT NULL COMMENT ‘数据来源,1移动端 2批量导入’,
sync_type int(11) DEFAULT NULL COMMENT ‘同步数据类型,0:未同步,1:已同步,2:同步中,3:异常数据’,
sync_count int(11) DEFAULT NULL COMMENT ‘同步数据类型,0:未同步,1:已同步,2:同步中,3:异常数据’,
flg varchar(20) NOT NULL DEFAULT ‘Y’ COMMENT ‘是否删除’,
ctime datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
mtime datetime DEFAULT NULL COMMENT ‘更新时间’,
create_user bigint(20) NOT NULL DEFAULT ‘-2’ COMMENT ‘创建用户’,
update_user bigint(20) DEFAULT NULL COMMENT ‘更新用户’,
val0 text DEFAULT NULL COMMENT ‘数表字字段值’,
val1 text DEFAULT NULL COMMENT ‘数据表字段值’,
val2 text DEFAULT NULL COMMENT ‘数据表字段值’,
val3 text DEFAULT NULL COMMENT ‘数据表字段值’,
val4 text DEFAULT NULL COMMENT ‘数表字字段值’,
val5 text DEFAULT NULL COMMENT ‘数据表字段值’,
val6 text DEFAULT NULL COMMENT ‘数据表字段值’,
val7 text DEFAULT NULL COMMENT ‘数据表字段值’,
val8 text DEFAULT NULL COMMENT ‘数表字字段值’,
val9 text DEFAULT NULL COMMENT ‘数据表字段值’,

是的 bigint = varchar 这样关联的

join on int equal string get the wrong result · Issue #13801 · pingcap/tidb (github.com)
应该算预期内现象,与mysql行为一致,看issue上官方没把这种行为算为bug,还是用cast转换看看吧,大于18位应该就会有问题,我之前也遇到过类似的
cast转换没法正常走索引 - :sun_with_face: 建议反馈 / 产品缺陷 - TiDB 的问答社区 (asktug.com)

1 个赞

加个引号试试

想办法改代码添加引号吧,其他的都不靠谱

字段类型和值类型不同,出现隐式转换现象,不管是从设计、维护、还是从性能等各方面考虑,都应该要避免。

建议要么调整代码,要么调整表结构类型。

text需要转成char吧

1 个赞