暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

改写SQL匹配条件逻辑一例

GrowthDBA 2021-12-10
996


反向逻辑改写正向逻辑




作为DBA一员,是不是很少写SQL啊,哈哈,俺也一样,今天在群里看到这样一个问题。

问题是:'!'代表什么意思。
我没有见过这样的写法,根据多年的经验判断,应该是取反的意思,比如,' != 1'表示不等于1。于是乎,有了下面的验证,并证实了自己的猜想。

'!'确实是取反的意思,同时也验证了一下:A AND B,A和B都为TRUE,整个表达式才为TRUE;A OR B,A或B任意一个为TRUE,整个表达式就为TRUE。同时,还有一个需要注意的点是:当同时出现AND和OR时,AND的优先级高于OR。
'!'的问题解决了,而我更在乎的是这个SQL匹配条件的逻辑:

匹配条件中有AND、OR、括号和取反操作,看的我一头雾水。对于逻辑思维一般的我来说,总想把这个匹配条件改成方便我能读懂的正向逻辑。然后经过一段时间的思考分析🤔,恩,没想出来。果断向郑松华老师寻求帮助,恩,很快啊,没有闪,直接就分析出这个条件的含义了。

条件的含义就是:handle_code = 200 或者 trigger_code IN (0,200) AND handle_code = 0 之外的所有记录
老师说完这句话后,感觉一下子理解了,接着,松华老师直接把正向的语句逻辑发了过来。

然后我按照条件的含义,模拟问题截图创建了一张测试表,并插入一些测试数据:

--Create TableCREATE TABLE t (    id INT(11) PRIMARY KEY AUTO_INCREMENT,    trigger_code INT(11) DEFAULT NULL,    handle_code INT(11) DEFAULT NULL,    alarm_status INT(11) DEFAULT NULL) ENGINE=InnoDB;--Insert Test DataINSERT INTO t VALUES(1, 0, 200, 666),(2, 666, 666, 0),(3, 666, 666, 0),(4, 200, 0, 666),(5, 666, 666, 0),(6, 0, 0, 666),(7, 666, 666, 0),(8, 0, 0, 0);--Query DataSELECT * FROM t;

测试原反向逻辑语句和改写逻辑后的语句执行结果是否一致:
SELECT * FROM t WHERE !((trigger_code IN (0,200) AND handle_code = 0) OR (handle_code = 200)) AND alarm_status=0 ORDER BY id ASC LIMIT 1000;SELECT * FROM t WHERE (handle_code<>200 and concat(handle_code ,trigger_code) not in ('00','0200')) AND alarm_status=0 ORDER BY id ASC LIMIT 1000;

是不是感觉一下通透了,由衷感谢郑松华老师的帮助。我平时很少写SQL,逻辑思维也相对薄弱,改写后的逻辑也需要仔细思考一下。希望通过今天这个小例子,能给大家带来一些改写SQL的技巧。今天就到这里吧。


文章转载自 GrowthDBA,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论