MySQL WHERE IN还是范围查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL WHERE IN还是范围查询相关的知识,希望对你有一定的参考价值。

参考技术A 线上出了一个bug:参与集福气活动的很多玩家奖励少发了。

要补发给玩家的奖励可以通过表A和奖励发放表计算得出(需要补发的奖励 = 表A - 实际奖励发放表)。

现在的做法是写个job把这份补发奖励的名单拉取来(没错不等关服维护了,直接在线跑job)。这里要强调一点:只有在“实际奖励发放表”存在的玩家才有可能需要补发奖励。

第三个方法是我用来凑数的,请各位千万不要这么做。除非实际奖励发放表中玩家人数只有个位数。那到底是用第一个还是第二个呢?这个问题主要看两点:

采用方法二:范围查询的方式把数据加到内存中然后再筛选

需要查询的mysql数据很多(玩家名单list有几万个),使用范围查找能加快查询速度并且即使将表A的数据全部加载在内存中job服务器也是没有压力。

MySQL查询语句

1.  基本知识:

单表查询
完整语句顺序:select..from..where..group by..haveing..order by..limit..
(1) where 条件:对表中的数据进行筛选和过滤
判断符号:> < = !=或者<> >= <=
拼接条件的关键字:not and or
查询区间的范围值:between..and..
查询具体某个值的范围:in(条件...)
模糊查询like:
"%a":匹配以a结尾的任意长度的字符串
"a%":匹配以a开头的任意长度的字符串
"%a%":匹配含有a字符的任意长度的字符串

模糊查询_:
"_a":匹配以a结尾的一共两个元素的字符串
"a__":匹配以a开头的一共三个元素的字符串

聚合函数:一般情况下聚合函数和分组配合使用
(1) count(*):统计总数
(2) max():取最大值
(3) min():取最小值
(4) avg():取平均值
(5) sum():统计总和

多表查询:
内连接:(内联查询 inner join ) -> 两表或者多表满足条件的所有数据查询出来(两表之间共有的数据)
select * from employee inner join department on employee.dep_id = department.id;
用as 起别名 (推荐):select * from employee as e inner join department as d on e.dep_id = d.id;
as 可以省略掉:select * from employee e inner join department d on e.dep_id = d.id;

where 默认实现的就是内联查询的效果
select * from employee , department where employee.dep_id = department.id;
select * from employee as e , department as d where e.dep_id = d.id;

两表查询:select 字段 from 表1 inner join 表2 on 必要的关联条件
多表查询:select 字段 from 表1 inner join 表2 on 必要的关联条件1 inner join 表3 on 必要的关联条件2 ...

外连接:
(1) 左连接(左联查询 left join) 以左表为主,右表为辅,完整查询左表所有数据,右表没有的数据补null
select * from employee left join department on employee.dep_id = department.id;
(2) 右链接(右联查询 right join)以右表为主,左表为辅,完整查询右表所有数据,左表没有的数据补null
select * from employee right join department on employee.dep_id = department.id;
(3) 全连接(全连接 union) 所有的数据都合并起来
select * from employee left join department on employee.dep_id = department.id
union
select * from employee right join department on employee.dep_id = department.id;

子查询: 嵌套查询
(1)sql语句当中又嵌套了另外一条sql语句,用包括()包起来,表达一个整体
(2)一般应用在from 子句后面表达一张表, where子句后面表达一个条件
(3)查询速度从快到慢 : 单表查询 -> 联表查询 -> 子查询

2.单表查询:
where语句:
1. 查看岗位是teacher的员工姓名、年龄
select emp_name,age from employee where post ="sale";
2. 查看岗位是teacher且年龄大于30岁的员工姓名、年龄 select emp_name,age from employee where post="teacher" and age>30;
3.
查看岗位是teacher且薪资在9000-1000范围内的员工姓名、年龄、薪资 select emp_name,age,salary from employee where post="teacher" and salary between 1000 and 9000;
4. 查看岗位描述不为NULL的员工信息 # 不为null,匹配应用is null或者is not null select * from employee where post_comment is not null;
5. 查看岗位是teacher且薪资是10000或9000或30000的员工姓名、年龄、薪资 select emp_name,age,salary from employee where salary in(10000,9000,30000);
6. 查看岗位是teacher且薪资不是10000或9000或30000的员工姓名、年龄、薪资 select emp_name,age,salary from employee where salary not in(10000,9000,30000);
7. 查看岗位是teacher且名字是jin开头的员工姓名、年薪 select emp_name,salary*12 from employee where post="teacher" and emp_name like"jin%";
8.起别名:concat,concat_ws select concat("姓名: ",emp_name,"工资: ",salary) as "员工工资表" from employee; select concat_ws(": ",emp_name,salary) as "工资条" from employee; group语句: group_concat:按照分类的形式对字段进行拼接 1. 查询部门名以及各部门的平均薪资 select post,avg(salary) as avg_salary from employee group by post;
2. 查询部门名以及各部门的最高薪资 select post,max(salary) from employee group by post;
3. 查询部门名以及各部门的最低薪资 select post,min(salary) from employee group by post;
4. 查询公司内男员工和女员工的个数 select sex,count(*) from employee group by sex;
5. 查询部门名以及部门包含的所有员工名字 select post,emp_name from employee group by post,emp_name; select group_concat(post,":",emp_name) from employee group by post; select group_concat(emp_name) from employee group by post; having语句:数据在分类分组之后,进行二次数据过滤,一般是配合group by 使用,分组之后再进行过滤 1.查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数 select post,group_concat(emp_name),count(*) from employee group by post having count(*)<2;
2.查询各岗位平均薪资小于10000的岗位名、平均工资 select post,avg(salary) as avg_salary from employee group by post having avg_salary<10000;
3.查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资 select post,avg(salary) as avg_salary from employee group by post having avg_salary between 10000 and 20000; select post,avg(salary) from employee group by post having avg(salary) > 10000 and avg(salary) < 20000; order by语句:默认升序asc 1. 查询所有员工信息,先按照age升序排序,如果age相同则按照hire_date降序排序 select * from employee order by age asc,hire_date desc;
2. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资升序排列 select post,avg(salary) as avg_salary from employee group by post having avg_salary>10000 order by avg_salary;
3. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列 select post,avg(salary) as avg_salary from employee group by post having avg_salary>10000 order by avg_salary desc; limit语句:limit m,n m代表从第几条数据查询,n代表查询几条, m=0 代表的是第一条,m=0代表数据库的第一条数据 select * from employee limit 0,5; #从第一条数据开始搜,查5条,也可以不写0,默认从0开始 select * from employee limit 5,5; #从第六条数据开始搜,查5条 select * from employee order by id desc limit 1; # 找数据库当中最后一条数据 (了解)可以使用正则表达式查询数据 (不推荐使用,效率不高) select * from employee where emp_name regexp ".*on$" # mysql里面的.*? 问号?不识别 select * from employee where emp_name regexp "^程"; select * from employee where emp_name regexp "^程.*金";

 

2. 多表查询:

一.找出平均年龄大于25岁以上的部门
方式一:
select d.name from employee as e,department as d where e.dep_id = d.id group by d.name having avg(age)>25;
方式二:
select d.name from employee as e inner join department as d group by d.name having avg(age)>25;
方式三:
select dep_id from employee group by dep_id having avg(age)>25;
select name from department where id in(select dep_id from employee group by dep_id having avg(age)>25);
二.查看技术部门员工姓名 方式一: select e.name
from employee as e,department as d where e.dep_id = d.id and d.name = "技术"; 方式二: select e.name from employee as e inner join department as d on e.dep_id = d.id where d.name = "技术"; 方式三: select id from department where name = "技术"; select name from employee where dep_id in(select id from department where name = "技术"); 三.查看哪个部门没员工
方式一: select d.name
from employee as e right join department as d on e.dep_id = d.id where e.dep_id is null; 方式二: select dep_id from employee; select name from department where id not in(select dep_id from employee); 四.查询大于平均年龄的员工名与年龄 select name,age from employee where age > (select avg(age) from employee); 五.把大于其本部门平均年龄的员工名和姓名查出来 select dep_id,avg(age) as avg_age from employee group by dep_id; # t2 select name from employee inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t2 on employee.dep_id = t2.dep_id where employee.age>t2.avg_age;
六.查询每个部门最新入职的那位员工
# 利用上一套数据表进行查询; select post , max(hire_date) as max_data from employee group by post select t1.emp_name,t1.hire_date from employee as t1 inner join (select post , max(hire_date) as max_data from employee group by post) as t2 on t1.post = t2.post where t1.hire_date = t2.max_data; 七.带EXISTS关键字的子查询 exists 关键字,表达存在 如果内层sql 能够查到数据,返回True , 外层sql执行查询语句 如果内层sql 不能查到数据,返回False, 外层sql不执行查询语句 select * from employee where exists (select * from employee where id = 1); # select * from employee where exists (select * from employee where id = 100) # 不能

 

以上是关于MySQL WHERE IN还是范围查询的主要内容,如果未能解决你的问题,请参考以下文章

MySQL-SQL查询

MySQL查询(未完结)

pandas使用query函数查询dataframe中某一个数据列在指定数据范围的数据行(rows where value is between two values in dataframe)

Mysql从入门到入魔——3. 查询排序WHERE过滤

mysql IN子句不使用可能的键

IN 查询