达梦(sql)的AND和OR使用踩坑留恋

前言:这段时间搞mongodb的项目去了,关系型数据库的使用又生疏了。火速捡起开学!罪过啊!


1.初见!

今天发版,顺带就看看生产环境的数据是否正常。结果发现一个巨离谱的数据,大概就像记录一个人的身高,别人机械自动测量出来是999cm,数据传给我们后我们的界面就直接就展示了。

额~于是马上加上数据清洗,把机械自动测量的数据先去除掉再返给前端。


2.再见!!

美滋滋改完自测后又发了一版,线上又看了下。有几个接口按预期进行了数据清洗返回了,但是身高999cm的这哥们又跑出来了,wtf?

来来来,改错题来了,各位看官请看题:

SELECT
        <include refid="Base_Column_List_E667"/>
        FROM EVENT E667
        <where>
            AND E667.EVENT_FROM != '1'
        <if  test="timeStampCode != null">
            AND (#{timeStampCode} = 1 AND E667.O_TIME between add_months(now(),-1)  and now())
            OR
            (#{timeStampCode} = 2 AND E667.O_TIME between add_months(now(),-1*6)  and now())
            OR
            (#{timeStampCode} = 3 AND E667.O_TIME between add_months(now(),-1*12)  and now())
        </if>
        </where>

问题:当timeStampCode为1时,能正常查出eventFrom不为1的数据,但是为2时就会出现eventFrom为1的数据。怪,我明明把AND E667.EVENT_FROM != '1'写在最前面了哇!这是为什么捏?

而且明明AND的优先级比OR高啊,百思不得其解。

 罚你重新去学sql! 罚你重新去学sql! 罚你重新去学sql!

3.解析

看似这样没问题,但当timeStampCode为2时,会生效该条件:

(#{timeStampCode} = 2 AND E667.O_TIME between add_months(now(),-1*6)  and now())

然而实际上该条件是通过 'OR' 连接到其他条件上的,而不是 'AND' 。所以,虽然AND E667.EVENT_FROM != '1'仍然存在,但它与其他条件没有逻辑连接,所以导致失效。

如何解决呢?

在条件之间加上括号即可,明确它们之间的逻辑连接关系。

以下是修正后的sql:

SELECT    
    <include refid="Base_Column_List_E667"/>
FROM EVENT E667
<where>    
    AND E667.EVENT_FROM != '1'    
    <if test="timeStampCode != null">        
        AND (            
            (#{timeStampCode} = 1 AND E667.O_TIME between add_months(now(),-1) and now())            
            OR
            (#{timeStampCode} = 2 AND E667.O_TIME between add_months(now(),-1*6) and now())                        
            OR
            (#{timeStampCode} = 3 AND E667.O_TIME between add_months(now(),-1*12) and now())                
        )   
    </if>    
</where>

还有种方法是在每个or语句后面都加上AND E667.EVENT_FROM != '1',但这样的后果是如果timeStampCode不符合条件时,where子句将为空,导致整个查询结果为空。


本人才疏学浅,各位就当看个乐子。再问就是yyz,哼

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值