表达式求反函数(入参: 原始表达式) {分词;语法树构建;语义解析构造优先级的bool表达式树;复杂条件求反 -> 代入现有解析好的bool表达式;}复杂条件求反(入参: bool表达式) {if 原子表达式:return 字典映射求反表达式;if 当前连接符是 'and':复杂条件求反 -> 代入左边的bool表达式;复杂条件求反 -> 代入左边的bool表达式;return 以上两个结果用'or'连接;if 当前连接符是 'or':复杂条件求反 -> 代入左边的bool表达式;复杂条件求反 -> 代入左边的bool表达式;return 以上两个结果用'and'连接;}字典映射求反表达式(入参: bool表达式) {为空 -> 不为空;等于 -> 不等于;大于 -> 小于等于;in -> not..in.....}可以看出,应该还是可行的,但是对于像优先级,括号,四则运算之类的处理,那应该是相当的复杂的 。对于非专业搞数据库开发,或者编译器的同学而言,应该是非常之难的 。具体咱也不知道,看你咯 。
3. sql语法巧用我们知道,一个sql的bool表达式,有true/false之分,正常情况下都是以 true 作为判断条件的 。比如 is null 为true, 那么 is not null 就为false 。=1为true, 那么 !=false, in 为true, 那么 not in 就为false 。between 为true, 那么 not between 就为false.
虽然情况很多,但是我们已经看到,sql中天然就有一个词代表了取反的意思 。只是好像只有特定的场景下才可以使用not关键词 。好像有点失望了 。
为什么不试一试呢?比如 x=1 的反义词是否可以是 not x = 1 ? 为测试方便,我们直接使用内存数据库sqllite测试, https://www.sqlite.org/download.html 。参考下载链接: https://www.sqlite.org/2022/sqlite-tools-win32-x86-3390400.zip
接下来我们用两张表测试下 。
-- 新建测试表1create table test1 (id int, name varchar(50),age int)-- comment '用户基础信息表';-- 新建测试表2create table test2 (uid int,salary double,company varchar(50))-- comment '用户工作信息表';-- 插入测试数据insert into test1 (id, name, age) values (1, 'zhangsan', 18);insert into test1 (id, name, age) values (2, 'lisi', 20);insert into test1 (id, name, age) values (3, 'wanger', 30);insert into test2 (uid, salary, company) values (1, 1000.1, 'axxx');insert into test2 (uid, salary, company) values (2, 2000.1, 'bxxx');insert into test2 (uid, salary, company) values (3, 3000.1, 'cxxx');接下来我们用not语法和非not语法测试下 。
sqlite> select * from test1 where name = 'zhangsan';1|zhangsan|18sqlite> select * from test1 where name != 'zhangsan';2|lisi|203|wanger|30sqlite> select * from test1 where not (name = 'zhangsan');2|lisi|203|wanger|30看起来语法是支持的,而且两个语法的简单语句执行结果居然是一样的 。接下来我们测试稍微复杂点的:
sqlite> select * from test1 where name = 'zhangsan' or name = 'lisi';1|zhangsan|182|lisi|20sqlite> select * from test1 where name != 'zhangsan' and name != 'lisi';3|wanger|30sqlite> select * from test1 where not( name = 'zhangsan' or name = 'lisi');3|wanger|30看起来多个条件的连接not语法也是支持的,而且结果也是正确的呢 。我们来测试一个三条件的语句:
sqlite> select * from test1 where name = 'zhangsan' or name = 'lisi' and age = 20;1|zhangsan|182|lisi|20sqlite> select * from test1 where name != 'zhangsan' and (name != 'lisi' or age != 20);3|wanger|30sqlite> select * from test1 where not (name = 'zhangsan' or name = 'lisi' and age = 20);3|wanger|30sqlite> select * from test1 where age > 20;3|wanger|30sqlite> select * from test1 where age <= 20;1|zhangsan|182|lisi|20sqlite> select * from test1 where not( age > 20 );1|zhangsan|182|lisi|20好吧,看起来单表的操作并没有问题 。会不会是因为单表简单的原因?我们试试多表join的:
sqlite> select t1.name,t1.age, t2.salary from test1 t1 left join test2 t2 on t1.id = t2.uid where t1.age >= 20 and t2.salary > 2000;lisi|20|2000.1wanger|30|3000.1sqlite> select t1.name,t1.age, t2.salary from test1 t1 left join test2 t2 on t1.id = t2.uid where t1.age < 20 or t2.salary <= 2000;zhangsan|18|1000.1sqlite> select t1.name,t1.age, t2.salary from test1 t1 left join test2 t2 on t1.id = t2.uid where not (t1.age >= 20 and t2.salary > 2000);zhangsan|18|1000.1
经验总结扩展阅读
- RedHat7.6安装mysql8步骤
- 抖音直播带货怎么吸引人 抖音直播带货吸引人方法技巧分享
- 华容道步骤(数字华容道技巧)
- 数字华容道的玩法与技巧(1-15数字华容道题库)
- 怎么玩三国华容道(华容道三国版技巧)
- [Oracle]复习笔记-SQL部分内容
- postman一些你不常用的实用技巧,竟然还能这么玩
- Cenots7 离线安装部署PostgreSQL
- 静电怎么消除的小窍门 静电如何去除的小技巧是什么
- 儿童房装修设计技巧 儿童房选什么颜色比较好

 
   
   
   
   
   
   
   
   
   
   
   
  