Mysql--对varchar字段用int数值来查询的问题

在工作中遇到的一个问题。就是mysql的一个表中的一个字段是varchar类型的,这个字段用来存储身份证,身份证正好是18位的。但是在根据身份证号来查询用户的时候,忘了给这个查询条件的身份证号加上’’,然后就产生了问题。

先来看表结构:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for kaoshi_user
-- ----------------------------
DROP TABLE IF EXISTS `kaoshi_user`;
CREATE TABLE `kaoshi_user`  (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `jgid` int(11) NULL DEFAULT NULL COMMENT '培训机构ID',
  `examid` int(11) NULL DEFAULT NULL COMMENT '考试ID',
  `username` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户姓名',
  `createtime` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
  `sex` int(3) NULL DEFAULT 0 COMMENT '性别(1男,2女,0未知)',
  `sfzh` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '身份证号',
  `dwname` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '单位名称',
  `zhiwu` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '职务',
  `xzarea` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '行政区域',
  `phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机号',
  `address` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '家庭住址,联系地址',
  `examtime` int(11) NULL DEFAULT NULL COMMENT '考试剩余时间',
  PRIMARY KEY (`ID`) USING BTREE,
  INDEX `sfzh`(`sfzh`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 236 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of kaoshi_user
-- ----------------------------
INSERT INTO `kaoshi_user` VALUES (110, 1, 1, '张三', '2020-04-27 14:25:38', 1, '330382199602254678', 'xxxx单位', 'xxxx职务', 'xxxx街道', '15058977786', 'xxx省xxx市xxxx', 3326);
INSERT INTO `kaoshi_user` VALUES (111, 1, 1, '张三', '2020-04-27 14:25:38', 1, '330382199602254672', 'xxxx单位', 'xxxx职务', 'xxxx街道', '15058977787', 'xxx省xxx市xxxx', 3600);
INSERT INTO `kaoshi_user` VALUES (112, 1, 1, '张三', '2020-04-27 14:25:38', 2, '330382199602254675', 'xxxx单位', 'xxxx职务', 'xxxx街道', '15058977788', 'xxx省xxx市xxxx', 2444);
INSERT INTO `kaoshi_user` VALUES (113, 1, 1, '张三', '2020-04-27 14:25:38', 1, '330382199602254679', 'xxxx单位', 'xxxx职务', 'xxxx街道', '15058977789', 'xxx省xxx市xxxx', 0);
INSERT INTO `kaoshi_user` VALUES (114, 1, 1, '张三', '2020-04-27 14:25:38', 1, '330382199602254673', 'xxxx单位', 'xxxx职务', 'xxxx街道', '15058977790', 'xxx省xxx市xxxx', 3600);
INSERT INTO `kaoshi_user` VALUES (115, 1, 1, '张三', '2020-04-27 14:25:38', 2, '330382199602254671', 'xxxx单位', 'xxxx职务', 'xxxx街道', '15058977791', 'xxx省xxx市xxxx', 3558);
INSERT INTO `kaoshi_user` VALUES (128, 1, 3, '张三', '2020-05-06 09:59:31', 1, '330382199602254678', 'xxxx单位', 'xxxx职务', 'xxxx街道', '15058977786', 'xxx省xxx市xxxx', 3784);
SET FOREIGN_KEY_CHECKS = 1;

接着来看sql语句:

select * from kaoshi_user where sfzh=330382199602254675

这条sql语句 本来以为只会查出 身份证号是330382199602254675的用户,没想到查询结果如下图:
在这里插入图片描述
但是把sql语句修改一下,在身份证号那个条件语句用字符串来查询,而不是整数,如:

select * from kaoshi_user where sfzh='330382199602254675'

在这里插入图片描述
查出来的结果那就只有这一条了。

明显上述sql语句在条件加单引号是符合我的要求的。但是不明白为什么用整数数值来查询会出现问题,在网上查询资料发现关于这方面的资料也很少。

后来在查询了官方文档后(MySql官方文档表达式中隐式类型转换),知道了结果。https://dev.mysql.com/doc/refman/5.7/en/type-conversion.html

得出的结论如下:

  1. 在字符串和数值作比较的时候,字符串和数值都会转换成浮点数进行比较。
  2. 字符串在转浮点数时,如果字符串开头是数字,那就一直截取,直到截取到的不是数字是其他字符为止。若开头不是数字,那么转换数值类型的结果就直接取0。(如’123abc’转成的值是123,'ab123’取到的值是0)
  3. 在上述中,我的字符串存储的是18位varchar类型。由于在转换成浮点数的时候,数值太大会自动转换成科学计数法,而且浮点数的精度不准确,都是取近似值,所以会出现意外的内容。也就是说我的查询sql条件在用数值类型时,由于数值太大了,所以在转换成浮点数的时候变成了科学计数法,同理被查询的字段也被转换成了浮点数的科学计数法,又由于浮点数精度的不准确,导致查询结果出现不准确。
  4. 如果用了字符串字段,在查询的时候最好不要用数值(如整数之类的)来查询,因为如果用数值查询,也就是如上面说的,MySql会自动把表达式中的值都转换成浮点数。而这里索引字段varchar类型进行自动转换成了浮点数,导致了索引失效。
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值