SQL-MySQL中连等或其他连续比较运算符逻辑

SQL-MySQL中连等或其他连续比较运算符逻辑

问题背景

  • 今天群里朋友忽然发了这么一条问题,问:“有见过mysql中的这种写法嘛,这是等价于and还是or”
    在这里插入图片描述

  • 然后群里几个小伙伴先是狂喷了一波是怎么写出这种狗屎SQL的。。随后探讨了一波这个问题

问题分析

  • 看到这张图的第一想法。。是根据结果去反推。
  • 反推的结果显然是or
  • 但想来想去。这样一个连续的比较运算符。凭什么就看作是or呢???
  • 越想越难受。去验证一波吧。。。

一次实验

  • 第一次准备了这些数据,想验证它到底是and还是or

  • 在这里插入图片描述

  • 使用这几条sql去验证

-- or的情况
SELECT * FROM test where a <= 12 or 12 <= c;
-- and的情况
SELECT * FROM test where a <= 12 and 12 <= c;
-- 待验证的逻辑
SELECT * FROM test where a <= 12 <= c;
  • 惊了!!待验证的返回的竟然是全部的数据集。。既不是and也不是or
  • 在这里插入图片描述
实验想法
  • 于是我回复他。可能是这个写法根本不合理,所以就相当于没有where条件吧
  • 但是回复了之后再转回头一想。sql里where子句是否命中走的不是三值逻辑(SQL-where子句谓词函数&三值逻辑)么??
  • 不合理的话。要不然是语法报错要不然是unknown呀?
  • unknown的数据是不会被命中返回的。被返回的只可能是计算为true的数据呀
  • 继续排查一波
  • 排查思路是,直接把它们select出来看看

二次实验

  • 执行SELECT a <= 12 <= c FROM test;

  • 发现执行的结果都是1

  • 在这里插入图片描述

  • 数据类型的bigint忽然点醒!表达式的的true和false是表现在一个int值上的

  • 那么在这个数据集中

    • 会不会是最左匹配先计算a <= 12,用得到的值和c进行匹配了(a <= 12) <= c?
    • 如果是这个情况的话就说得通了,(a <= 12)不管是true还是false,都表示为0或者1,在这个数据集中,C的值我都设置的是大于这个的
  • 先继续用这个数据集验证,重新展示数据集(发现B并没有什么用。把B这个字段移除了)

  • 在这里插入图片描述

  • 把这个表达式中的<=变成<试一下

  • 如果刚刚的猜想没错,返回的结果集应该是

    1. (a < 12)为false,0 < 13 结果为true,命中
    2. (a < 12)为true,1 < 13 结果为true,命中
    3. (a < 12)为true,1 < 1 结果为false,不命中
    4. (a < 12)为false,0 < 1 结果为true,命中
  • SELECT * FROM test where a < 12 < c;

  • 在这里插入图片描述

  • 结果不出所料

  • 但还需要一个小实验证明一下

三次实验

  • 准备数据集

  • 在这里插入图片描述

  • 分别查询sql:

    • SELECT * FROM test where a < 12 < c;
    • SELECT * FROM test where a <= 12 <= c;
  • 结果分别为:

    • 在这里插入图片描述

    • 在这里插入图片描述

  • 再配合一条:SELECT a < 12, c, a < 12 < c FROM test;

  • 在这里插入图片描述

  • 结果很显然,只有在a < 12这一列的值与c的比较运算符的结果决定了a < 12 < ca <= 12 <= c的结果,这些结果也与where子句命中的情况相符

问题解决

  • SQL中的连续比较运算符,是有最左优先计算的原则的
  • 哪怕是四个、五个连续的比较,也是同样的逻辑,例如:
    • a <= 12 <= c > c = 0
    • 只需要按(((a <= 12) <= c) > c) = 0来看
    • 如果a、c分别为13、1,就可以转化为13 <= 12 = false(0) --> 0 <= 1 = true(1) --> 1 > 1 = false(0) --> 0 = 0 --> true(1)
    • 来看出这行13、1的数据会被命中
  • 结论:MySQL中连续的比较运算符,按结合律的方式,把boolean值转换为int值,再进行后续的运算
  • 30
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值