zoukankan      html  css  js  c++  java
  • mysql中运用条件判断筛选来获取数据

    ### part1 单表查询

    sql查询完整语法:

    select .. from .. where .. group by .. having .. order by .. limit ..

    一.where 条件的使用

    """功能:对表中的数据进行过滤筛选"""
    """
    语法:
    	1.判断条件的符号
    	= > < >= <= != <>(不等于)
    	2.拼接条件关键字
    	and or not
    	3.查询区间范围值
    	between 小值 and 大值 [小值,大值] 查找两者之间的范围
    	4.查找某个具体范围值
    	in(值1,值2,值3) 在括号里这个范围内查询
    	5.模糊查询 like '%' 通配符
    		like '%a'  匹配以a结尾的任意长度的字符串
    		like 'a%'  匹配以a开头的任意长度的字符串
    		like '%a%' 匹配字符串中含有a字符的字符串
    		like '_a'  一共是2个长度,以a结尾,前面那个字符是什么无所谓
    		like 'a__' 一共是3个长度,以a开头,后面是什么字符无所谓
    """
    
    # (1) 单条件查询:
    # 查询部门是sale的所有员工姓名:
    select emp_name from  employee where post = 'sale';
    
    # (2) 多条件查询
    # 部门是teacher,并且收入大于10000的所有数据
    select * from employee where post = "teacher" and salary > 10000 ;
    
    # (3) 关键 between .. and 
    # 收入在1万到2万之间的所有姓名和收入
    select emp_name,salary from employee where salary between 10000 and 20000;
    # 收入不在1万到2万之间的所有姓名和收入
    select emp_name,salary from employee where salary not between 10000 and 20000;
    
    # (4) 关键字is null (判断某个字段是不是null , 不能用等号, 只能用is)
    # 查询 post_comment 是空的 null
    select emp_name,salary,post_comment from employee where post_comment is null;
    # 表达 post_comment 不是空的 is not null
    select emp_name,salary,post_comment from employee where post_comment is not null;
    select emp_name,salary,post_comment from employee where post_comment = null;
    
    # 设置一个值是空的
    update employee set post_comment = '' where id = 3;
    select emp_name,salary,post_comment from employee where post_comment = '';
    
    # (5) 关键字in的查询
    # 查收入是 3000 或者 2500 或者 4000 或者9000的所有员工和收入.
    select emp_name,salary from employee where salary=3000 or salary=2500 or salary=4000 or salary=9000;
    # 优化: 在当前括号里面查找
    select emp_name,salary from employee where salary in(3000,2500,4000,9000);
    # 在这个范围用in ,不在这个范围用not in
    select emp_name,salary from employee where salary not in(3000,2500,4000,9000,3000.13);
    
    # (6) 关键字like 模糊查询
    # 1. 通配符 %
    select * from employee where emp_name like "%on";
    # 2. 通配符 _
    select * from employee where emp_name like "a_e_";
    
    # (7) concat sql内置函数 concat(参数1,参数2,参数3) 把所有参数拼接在一起
    # as 用来起别名
    select emp_name,concat("姓名:",emp_name,"薪水:",salary) as ss  from employee;
    # concat_ws("符号",参数1,参数2,参数3) 第一个参数是分隔符,后面写上要拼接的参数
    select emp_name,concat_ws(" : ",emp_name,salary) as aa from employee;
    # 在sql中可以做四则运算(+ - * /)
    select emp_name,concat_ws(" : ",emp_name,salary*12) as aa from employee;
    

    二.group by 分组:

    """group by 分组分类 by 后面的字段 一般是select 后面要搜索的字段"""
    select post from employee where depart_id > 1 group by post
    # group_concat 按照分组的形式拼接字段
    select group_concat(emp_name),post from employee where depart_id > 1 group by post;
    
    # 聚合函数:
    	# 统计总数   count *代表所有.
    	select count(*) from employee;
    	# 统计最大值 max
    	select max(salary) from employee;
    	# 统计最小值 min
    	select min(salary) from employee;
    	# 统计平均值 avg
    	select avg(salary) from employee;
    	# 统计总和sum
    	select sum(salary) from employee;
    
    # 一般来说 分组 + 聚合函数在一起使用
    	# 求各部门的平均工资
    	select post,avg(salary) from employee group by post
    	select depart_id,avg(salary) from employee group by depart_id
    	# 查询部门名以及各部门的最高薪资
    	select post,max(salary) from employee group by  post
    	# 查询公司内男员工和女员工的个数
    	select sex,count(*)  from employee group by sex
    	# 查询部门名以及部门包含的所有员工名字
    	select post,emp_name from employee group by post,emp_name
    	select group_concat(emp_name),post from employee group by post;
    

    三.having 查询数据之后在进行过滤 , 一般是配合group by 使用,主要用于分组之后在过滤

    # 比如:求各个部门平均薪资,找出平均薪资大于10000以上的所有部门
    select post,avg(salary) from employee group by post having avg(salary) > 10000;
    # 1.查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
    select post,count(*),group_concat(emp_name) from employee group by post having count(*) < 2
    # 2.查询各岗位平均薪资小于10000的岗位名、平均工资
    select post,avg(salary) from employee group by post having avg(salary) < 10000;
    # 3.查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
    (1)select post,avg(salary) from employee group by post having avg(salary) > 10000 and avg(salary) < 20000
    (2)select post,avg(salary) from employee group by post having avg(salary) between 10000 and 20000;
    

    四.order by 按照什么字段排序

    # 默认升序asc 从小到大排序
    select  emp_name,age,post from employee order by age
    select  emp_name,age,post from employee order by age asc
    # 倒序 desc 从大到小排序
    select emp_name from employee where post ="teacher" order by age desc
    # 1. 查询所有员工信息,先按照age升序排序,如果age相同则按照hire_date降序排序
    select * from employee order by age asc , hire_date desc
    # 2. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资升序排列
    select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) asc;
    # 3. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列
    select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) desc;
    

    五.limit 限制查询的条数[用于做数据分页]

    # limit m,n 默认m值是0 代表第一条数据,n所代表的是查询几条,从m+1条件开始,查询n条数据
    select * from employee limit 0,5
    # 从第6条,继续往下搜,搜5条数据.
    select * from employee limit 5,5
    # 从第11条,继续往下搜,搜5条数据.
    select * from employee limit 10,5
    
    # 查询最后一条数据 limit 一个参数,就是查询几条的意思.
    select * from employee order by id desc limit 1
    select * from employee order by id desc limit 3
    

    六.使用正则表达式查询数据(了解,不好用,查询速度慢,部分结果与python 不一致)

    select * from employee where emp_name regexp 'on$';
    select * from employee where emp_name regexp '^程';
    select * from employee where emp_name regexp '程.*金'; # .*? 这里的?号识别不了
    

    ### part2 多表查询

    # 内连接(内联查询 inner join ) : 两表或者多表满足条件的数据查询出来 [表与表之间都有的部分会查出来]
    """
    语法: 
    	双表的内联:select 字段 from 表1 inner join  表2 on 条件
    	多表的内联:select 字段 from 表1 inner join  表2 on 条件 inner join 表3 on 条件 ... ... 
    """
    # 基本写法:
    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
    
    # 外连接
    	#(1)左连接(左联查询 left join): 以左表为主,右表为辅,完整查询左表数据,右表没有的数据补null
    	"""select 字段 from 表1 left join 表2 on 条件"""
    	select * from employee left join department on employee.dep_id =  department.id
    	#(2)右链接(右联查询 right join):以右表为主,左表为辅,完整查询右表数据,左表没有的数据补null
    	"""select 字段 from 表1 right join 表2 on 条件"""
    	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:找出年龄大于25岁的员工姓名及所在部门名字
    	# 内联:
    	select 
    		employee.id , employee.name as en , department.name as dn
    	from 
    		employee inner join department on employee.dep_id = department.id
    	where 
    		age > 25
    
    	# 例子2:查询employee 和 department 关联数据,以age字段升序排序
    	
    	# 内联
    	select 
    			*
    	from 
    		employee inner join department on employee.dep_id = department.id
    	order by 
    		age desc
    		
    	# where写法:
    	select *
    	from 
    		employee,department
    	where
    		 employee.dep_id = department.id
    	order by
    		age desc
    

    ### part3 子查询

    """
    子查询:嵌套查询
    	1.子查询是讲一个查询语句嵌套在另外一个查询语句之中,用括号()抱起来,表达一个整体
    	2.一般应用在from 或者 where 或者 字段中 .子查询这个整体可以作为表,也可以作为where 后面条件表达式
    	3. 速度从快到慢: 单表查询速度最快 >  其他是联表操作 > 子查询
    """
    
    # (1)找出平均年龄大于25岁以上的部门
    # 1.普通的where 联表查询
    select 
    	d.name ,d.id
    from 
    	employee e ,department  d
    where 
    	e.dep_id = d.id
    group by 
    	d.id,d.name 
    having 
    	avg(e.age) > 25
    
    # 2.内联查询
    select 
    	d.id,d.name 
    from 
    	employee e inner join department d on e.dep_id = d.id
    group by 
    	d.id,d.name 
    having 
    	avg(e.age) > 25
    
    # 3.子查询
    # 1.先选出平均年龄大于25岁的部门id
    select dep_id from employee group by dep_id  having avg(age) > 25;
    # 2.根据结果,选出在这个范围中的数据
    select name from department where id in(201,202)
    # 综合拼接:
    select 
    	name 
    from 
    	department 
    where 
    	id in(select dep_id from employee group by dep_id  having avg(age) > 25)
    
    
    
    # (2)查看技术部门员工姓名
    # 1.普通的where 联表查询
    select 
    	 e.name
    from 
    	employee e ,department d
    where
    	e.dep_id = d.id and d.name = "技术"
    
    # 2.内联查询
    select 
    	e.name
    from 
    	employee e inner join department d on e.dep_id = d.id
    where
    	d.name = "技术";
    
    # 3.子查询
    # 1.找技术部门对应的id是谁
    select id from department where name = "技术"
    # 2.通过id找员工姓名
    select name from employee dep_id = ?
    # 3.综合拼接
    select name from employee where  dep_id = (select id from department where name = "技术")
    
    
    # (3)查看哪个部门没员工
    # 右联方法:
    select 
    	 d.name
    from 
    	employee e right join department d on e.dep_id = d.id 
    where 
    	e.dep_id is null
    	
    # 子查询:
    # (1) 先查询 员工都在哪些部门
    select dep_id from employee group by dep_id
    # (2) 把不在部门列表中的这个部门找出来
    select id from department where id not in ?
    # 综合拼接
    select id from department where id not in(select dep_id from employee group by dep_id)
    
    
    # (4)查询大于平均年龄的员工名与年龄
    # 假如平均年龄是28岁
    select * from 表 where age > 28
    # 找平均年龄
    select avg(age) from employee
    # 综合拼接
    select name,age from employee where age > (select avg(age) from employee)
    
    
    # (5)把大于其本部门平均年龄的员工名和姓名查出来
    select * from employee
    

    +----+------------+--------+------+--------+
    | id | name | sex | age | dep_id | avg(age)
    +----+------------+--------+------+--------+
    | 1 | egon | male | 18 | 200 | 10
    | 2 | alex | female | 48 | 201 | 11
    | 3 | wupeiqi | male | 38 | 201 | 11
    | 4 | yuanhao | female | 28 | 202 | 13
    | 5 | liwenzhou | male | 18 | 200 | 10
    | 6 | jingliyang | female | 18 | 204 | 15
    +----+------------+--------+------+--------+

    #(1) 先计算各个部门平均年龄
    select dep_id,avg(age) from employee group by dep_id;
    #(2) 让子查询单独作为一张临时表和employee联表变成一张更大的表
    select * 
    from 
    	employee t1 inner join
    	(select dep_id,avg(age) age from employee group by dep_id) as t2
    	on t1.dep_id = t2.dep_id
    #(3) 让这张大表,当成一次单表查询;
    select * 
    from 
    	employee t1 inner join
    	(select dep_id,avg(age) as age from employee group by dep_id) as t2
    	on t1.dep_id = t2.dep_id
    where 
    	t1.age > t2.age
    
    # (6)查询每个部门最新入职的那位员工  # 利用上一套数据表进行查询;
    """
    # 每个部门都对应很员工,每个员工都对应一个入职时间,如果这时间最大就代表放入职
    """
    # 找每个部门的最大入职时间
    	select post,max(hire_date) from employee group by post;
    

    +----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    | id | emp_name | sex | age | hire_date | post | post_comment | salary | office | depart_id | max时间
    +----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    | 1 | egon | male | 18 | 2017-03-01 | 老男孩驻沙河办事处外交大使 | NULL | 7300.33 | 401 | 1 | 1
    | 2 | alex | male | 78 | 2015-03-02 | teacher | NULL | 1000000.31 | 401 | 1 | 2
    | 3 | wupeiqi | male | 81 | 2013-03-05 | teacher | | 8300.00 | 401 | 1 | 3
    | 4 | yuanhao | male | 73 | 2014-07-01 | teacher | NULL | 3500.00 | 401 | 1 | 4
    | 5 | liwenzhou | male | 28 | 2012-11-01 | teacher | NULL | 2100.00 | 401 | 1 | 5
    | 6 | jingliyang | female | 18 | 2011-02-11 | teacher | NULL | 9000.00 | 401 | 1 |
    | 7 | jinxin | male | 18 | 1900-03-01 | teacher | NULL | 30000.00 | 401 | 1 |
    | 8 | 成龙 | male | 48 | 2010-11-11 | teacher | NULL | 10000.00 | 401 | 1 |
    | 9 | 歪歪 | female | 48 | 2015-03-11 | sale | NULL | 3000.13 | 402 | 2 |
    | 10 | 丫丫 | female | 38 | 2010-11-01 | sale | NULL | 2000.35 | 402 | 2 |
    | 11 | 丁丁 | female | 18 | 2011-03-12 | sale | NULL | 1000.37 | 402 | 2 |
    | 12 | 星星 | female | 18 | 2016-05-13 | sale | NULL | 3000.29 | 402 | 2 |
    | 13 | 格格 | female | 28 | 2017-01-27 | sale | NULL | 4000.33 | 402 | 2 |
    | 14 | 张野 | male | 28 | 2016-03-11 | operation | NULL | 10000.13 | 403 | 3 |
    | 15 | 程咬金 | male | 18 | 1997-03-12 | operation | NULL | 20000.00 | 403 | 3 |
    | 16 | 程咬银 | female | 18 | 2013-03-11 | operation | NULL | 19000.00 | 403 | 3 |
    | 17 | 程咬铜 | male | 18 | 2015-04-11 | operation | NULL | 18000.00 | 403 | 3 |
    | 18 | 程咬铁 | female | 18 | 2014-05-12 | operation | NULL | 17000.00 | 403 | 3 |
    +----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
    """
    先把需要连接的字段查出来(最大值),然后在和旧表连接成想要的新表数据,从这个新的大表当中,搜索想要的字段.
    """
    select
    *
    from
    employee as t1 inner join
    (select post,max(hire_date) as max_date from employee group by post) as t2
    on t1.post = t2.post
    where
    t1.hire_date = t2.max_date

    # (7)带EXISTS关键字的子查询
    """
    exists 关键字表示存在
    	如果内层sql能够查到数据,返回真True,外层sql执行查询操作
    	如果内层sql不能查到数据,返回False ,外层sql 就不执行查询操作;
    """
    select * from employee
    where exists
    (select * from department where id = 200)
    

    总结:

    """
    子查询可以单独作为一个子句,也可以作为一个表或者某个字段
    一般用在where from select 后面的一个字段
    通过查询出来的临时表,可以在和其他表数据进行联接,形成一张更大的表.
    然后可以把更大的表当成一次单表查询操作,拿出想要的字段和条件完成任务;
    """
  • 相关阅读:
    java数据结构-循环链表实现
    java数据结构-普通链表实现测试
    java数据结构-普通链表实现
    java数据结构-排序算法-插入算法
    java数据结构-排序算法-快排算法
    java数据结构-递归算法-简单递归算法
    python------------------异常处理
    自定义Web框架
    Django框架第一篇
    Django框架之第二篇
  • 原文地址:https://www.cnblogs.com/caiwenjun/p/11945408.html
Copyright © 2011-2022 走看看