sql语句decimal_问了几个人,竟没一个能解答,这个SQL问题真有这么复杂?

058bca87e6c63f41648f2ff4a8f34203.png

“数据库里明明没有符合条件的数据,为什么结果还是有数据返回”,最近好几个同事差一点被这个问题难住了。

事情是这样的,前几天,一个在生产环境运行了好几个月的功能在测试环境调试发生了一个异常,也就是数据库里明明没有某个用户的数据,但在实际查询时却返回了一些无关数据,导致一个本来应该判断为空的逻辑,结果判断为不为空。

定位了好久,后来终于找到了问题所在。原来,就是下面这个SQL查询语句出现了问题。

8d14680ed21de264aa9cac8d599c52e1.png

结合上面的SQL语句和下面的表结构,大家也可以思考思考,如果让你来执行这个SQL,你能预知结果吗?为什么?

7e4845c59c58ca6367673cb74df90241.png

相信很多人会认为,这结果就是空,但实际呢?

f42da0d6d4859baa42831b53dd5b67a5.png

实际上,如上图所示,结果不为空。

要解释这样的结果,那就不得不说MySQL中数据类型的隐式转换。

在MySQL中,当操作符与不同类型的操作数一起使用时,会发生类型隐式转换以使操作数兼容。在MySQL中,数据类型隐式转换的规则主要有以下几条:

  1. 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=> 对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换
  2. 两个参数都是字符串,会按照字符串来比较,不做类型转换
  3. 两个参数都是整数,按照整数来比较,不做类型转换
  4. 十六进制的值和非数字做比较时,会被当做二进制串
  5. 有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为 timestamp
  6. 有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数,会将整数转换为 decimal 后进行比较,如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较
  7. 所有其他情况下,两个参数都会被转换为浮点数再进行比较

前面提到的执行异常的SQL查询语句,满足第7条,也就是name和false会被先转换成浮点数,然后再做比较。

在Mysql中,以数字开头的字符串,转换成浮点数时,会直接使用开头的数字;而不是以数字开头的字符串,转换成浮点数时,会直接变成0。如下:

205ce999f75921db96901e2574148f0b.png

至于bool值,false转换成浮点型会变成0,true转换成浮点型会变成1。如下:

7abdfc1224910788a25bc40d90aae574.png

这样一来,原来的SQL语句,在实际执行时就变成了下面这样:

9d421ca9d7aaa92da81f33a3229bdf46.png

如此一来,当然就可以查出数据来呀。唉,真是“一文钱难倒英雄汉”。

以后写SQL查询语句时,一定要确保查询条件的类型与数据库对应字段类型是一致的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值