数据库相关链接:
数据库–数据类型:http://t.csdn.cn/RtqMD
数据库–三大范式、多表查询、函数sql:http://t.csdn.cn/udJSG
数据库–MySQL增删改查:http://t.csdn.cn/xkiti
一、一条sql语句通常包括:
select from join where group by having order by 聚合函数 limit top
以及逻辑运算符not andor
一: 语法顺序
1. select
…
2. from
…
3. where
…
4. group by
…
5. having
…
6. order by
…
以上关键字只能按照这个顺序来, 不能颠倒
二: 执行顺序
1. from
2. where
3. group by //分组
4. having //过滤
5. select
6. order by //排序1> 从某张表中查询数据
2> 先经过where条件筛选出有价值的数据
3> 对这些有价值的数据进行分组
4> 分组之后可以使用 having 继续过滤筛选
5> select 查询出来
6> 最后排序输出
二、浅谈执行顺序:
1)、首先确定一点,并不是按照我们写的语句顺序,从左—>右执行的
2)、获取结果集 —-> 指定查询的某些字段 –> 按照某些内容进行排序
首先 执行from ,join 确定表之间的关系,得到初步的—–>结果集1
where 对结果集1 进行筛选 得到–>结果集2
group by 进行分组 –>结果集3
对结果集3进行having筛选,得到 —->结果集 4
指定查询的字段:
select 指定需要查询的字段,也可以是聚合函数 —>结果去重
合并分组结果集,并按照order by 的 条件进行排序
如果存在limit 或者top之类的话,这是在最后才会执行的
三、实际问题and or
mybatisplus遇到的and和or优先级的问题处理
需求:
想在name={ 张三,李四,王五 }中查找密码=88888或者年龄=20的记录
SELECT id,user_name,password,name,age,email,birthday FROM tb_userWHERE password = 88888 OR age >= 20 AND name IN ("张三","李四","王五")
java查询代码:
(使用MyBatisPlus查询)
@Testpublic void testLogicSelect(){QueryWrapper wrapper = new QueryWrapper();wrapper.eq("password","88888").or().ge("age",20).in("name","张三","李四","王五");/** * SELECT id,user_name,password,name,age,email,birthday FROM tb_user * WHERE password = " />User(id=1, userName=zhangsan, password=88888, name=张三, age=18, email=test1@yh.cn, birthday=2019-09-26T11:42:01)User(id=2, userName=lisi, password=88888, name=李四, age=20, email=test2@yh.cn, birthday=2019-10-01T11:42:08)User(id=3, userName=wangwu, password=88888, name=王五, age=28, email=test3@yh.cn, birthday=2019-10-02T11:42:14)User(id=4, userName=zhaoliu, password=88888, name=赵六, age=21, email=test4@yh.cn, birthday=2019-10-05T11:42:18)
问题的根本原因就是在于这个 AND 和 OR 的优先级。关系型运算符优先级高到低为:NOT > AND > OR
wrapper.eq("password","88888").or().ge("age",20).in("name","张三","李四","王五");
1. 先执行了后两句.ge(“age”,20)
.in(“name”,”张三”,”李四”,”王五”);
2. 将1.执行结果和第一句进行or或运算
.eq(“password”,”88888″)
.or()
.ge(“age”,20)
.in(“name”,”张三”,”李四”,”王五”);
解决方案:
这里用到了lambda表达式,从格式化后的代码也可以看出运算级别。
代码里的wp名字随便起,但是不能是wrapper,即不能是wrapper = new QueryWrapper();
@Testpublic void testLogicSelect() {QueryWrapper wrapper = new QueryWrapper();wrapper.and(wp -> wp //这里的wp名字随便起,但是不能是wrapper,即不能是wrapper = new QueryWrapper();.eq("password", "88888").or().ge("age", 20)).in("name", "张三", "李四", "王五");/** * SELECT id,user_name,password,name,age,email,birthday FROM tb_user * WHERE password = ? OR age >= ? AND name IN (?,?,?) */List userList = userMapper.selectList(wrapper);userList.forEach(System.out::println);}
小结:
第一句话:从执行顺序中我们可以发现,所有的查询语句都是从FROM开始执行的。
第二句话:在实际执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。
第三句话:关系型运算符优先级高到低为:NOT > AND > OR
看到这了,点个赞再走吧!