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 后面的一個字段
通過查詢出來的臨時表,可以在和其他表數據進行聯接,形成一張更大的表.
然后可以把更大的表當成一次單表查詢操作,拿出想要的字段和條件完成任務;
"""


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM