MySql的用法總結-2
本節內容:
一、單表查詢
二、多表查詢
三、子查詢
一、 單標查詢
1、where 條件的使用
功能:對錶中的資料進行篩選和過濾
語法:
1.判斷的符號
> < >= <= = !=( <>不等於 )
2.拼接不同條件的關鍵字
and or not
3.查詢區間值
between 小值 and 大值 [小值,大值] 查詢兩者之間的範圍
4.查詢區間值
id in (1,2,3,4,5,6)
5.模糊查詢 like %萬用字元 _萬用字元
like "%b" 匹配以b結尾的任意長度字串
like "a%" 匹配以a開頭的任意長度字串
like "%c%" 匹配字串中含有c的任意長度字串
like "__d" 匹配總長度為3位,而且以d結尾的字串
like "e__" 匹配總長度為3位,而且以e開頭的字元
1 #建立表 2 create table employee( 3 id int not null unique auto_increment, 4 emp_name varchar(20) not null, 5 sex enum('male','female') not null default 'male', #大部分是男的 6 age int(3) unsigned not null default 28, 7 hire_date date not null, 8 post varchar(50), 9 post_comment varchar(100), 10 salary double建立表(15,2), 11 office int, #一個部門一個屋子 12 depart_id int 13 ); 14 15 16 #三個部門:教學,銷售,運營 17 insert into employee(emp_name,sex,age,hire_date,post,salary,office,depart_id) values 18 ('egon','male',18,'20170301','老男孩駐沙河辦事處外交大使',7300.33,401,1), #以下是教學部 19 ('alex','male',78,'20150302','teacher',1000000.31,401,1), 20 ('wupeiqi','male',81,'20130305','teacher',8300,401,1), 21 ('yuanhao','male',73,'20140701','teacher',3500,401,1), 22 ('liwenzhou','male',28,'20121101','teacher',2100,401,1), 23 ('jingliyang','female',18,'20110211','teacher',9000,401,1), 24 ('jinxin','male',18,'19000301','teacher',30000,401,1), 25 ('成龍','male',48,'20101111','teacher',10000,401,1), 26 27 ('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是銷售部門 28 ('丫丫','female',38,'20101101','sale',2000.35,402,2), 29 ('丁丁','female',18,'20110312','sale',1000.37,402,2), 30 ('星星','female',18,'20160513','sale',3000.29,402,2), 31 ('格格','female',28,'20170127','sale',4000.33,402,2), 32 33 ('張野','male',28,'20160311','operation',10000.13,403,3), #以下是運營部門 34 ('程咬金','male',18,'19970312','operation',20000,403,3), 35 ('程咬銀','female',18,'20130311','operation',19000,403,3), 36 ('程咬銅','male',18,'20150411','operation',18000,403,3), 37 ('程咬鐵','female',18,'20140512','operation',17000,403,3) 38 ;
1 # 1. 查詢部門是sale的所有員工姓名: 2 select emp_name from employee where post="sale" 3 4 # 2. 部門是teacher , 收入大於10000的所有資料 5 select * from employee where post="teacher" and salary > 10000; 6 7 # 3. 收入在1萬到2萬之間的所有員工姓名和收入 8 select emp_name,salary from employee where salary between 10000 and 20000; 9 10 # 4. 收入不在1萬到2萬之間的所有員工姓名和收入 11 select emp_name,salary from employee where salary not between 10000 and 20000; 12 13 # 5. 檢視崗位描述為NULL的員工資訊 14 select * from employee where post_comment is null; 15 update employee set post_comment = "" where id = 1; 16 select * from employee where post_comment = ""; 17 # 檢視崗位描述不為NULL的員工資訊 18 select * from employee where post_comment is not null; 19 20 # 6. 查詢收入是3000 ,4000 ,5000,8300 所有員工的姓名和收入 21 select emp_name,salary from employee where salary in(3000,4000,5000,8300); # (推薦) 22 select emp_name,salary from employee where salary = 3000 or salary = 4000 or salary = 5000 or salary = 8300; 23 24 # 查詢收入不是3000 ,4000 ,5000,8300 所有員工的姓名和收入 25 select emp_name,salary from employee where salary not in(3000,4000,5000,8300); # (推薦) 26 27 # 7. 以on結尾的員工名搜一下 28 select emp_name from employee where emp_name like "%on"; 29 select emp_name from employee where emp_name like "wu%"; 30 select emp_name from employee where emp_name like "%le%"; 31 select emp_name from employee where emp_name like "al__"; 32 select emp_name from employee where emp_name like "%alex%"; 33 34 # 8. 統計員工一年的年薪 35 select concat("姓名:",emp_name,"收入:",salary) from employee; 36 # + - * / 四則運算 37 select concat("姓名:",emp_name,"收入:",salary * 12 ) from employee; 38 # 語法: concat_ws(拼接符號,欄位1,欄位2,欄位3 .... ) 39 select concat_ws(" : ",emp_name,salary * 12 ) from employee; 40 41 # 9. 查詢部門的種類 42 # distinct 去重 43 select distinct(post) from employee練習:where 拼接條件
2、 group by 子句 分類,分組
注意點: 針對於當前表,by誰搜誰
select sex from employee group by sex select emp_name from employee group by sex # error # group_concat 按照分組把對應的欄位拼接在一起 select group_concat(emp_name) from employee group by sex;
# 聚合函式 # 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;
1 #練習:group 分類 2 # 1. 查詢部門名以及各部門的平均薪資 3 select avg(salary),post from employee group by post 4 5 # 2. 查詢部門名以及各部門的最高薪資 6 select max(salary),post from employee group by post 7 8 # 3. 查詢部門名以及各部門的最低薪資 9 select min(salary),post from employee group by post 10 11 # 4. 查詢公司內男員工和女員工的個數 12 select count(*),sex from employee group by sex 13 14 # 5. 查詢部門名以及部門包含的所有員工名字 15 select group_concat(emp_name),post from employee group by post; 16 17 # 6. 可以group by 兩個欄位,by誰搜誰; 18 select emp_name,post from employee group by post,emp_name;練習:group 分類
3、.having 對分類後的資料進行二次過濾[應用在group by這個場景裡]
1 # 找出各部門平均薪資,且大於10000 2 select post,avg(salary) from employee group by post having avg(salary) > 10000 3 4 # 1.查詢各崗位內包含的員工個數小於2的崗位名、崗位內包含員工名字、個數 5 select group_concat(emp_name),post,count(*) from employee group by post having count(*) > 2 6 7 # 2.查詢各崗位平均薪資小於10000的崗位名、平均工資 8 select post,avg(salary) from employee group by post having avg(salary) < 10000 9 10 # 3.查詢各崗位平均薪資大於10000且小於20000的崗位名、平均工資 11 select post,avg(salary) from employee group by post having 10000 < avg(salary)< 20000 error[沒有搜到想要的結果] 12 select post,avg(salary) from employee group by post having 10000 < avg(salary) and avg(salary) < 20000 13 # 10000 <= avg(salary) <= 20000 14 select post,avg(salary) from employee group by post having avg(salary) between 10000 and 20000;練習:having
4、.order by 排序
- 正序 升序 asc
- 倒序 降序 desc
#練習:order by select * from employee order by age; select * from employee order by age asc;(預設升序) select * from employee order by age desc;(預設升序)
1 # 1. 查詢所有員工資訊,先按照age升序排序,如果age相同則按照 hire_date 降序排序 2 select * from employee order by age asc , hire_date desc; 3 # 2. 查詢各崗位平均薪資大於10000的崗位名、平均工資,結果按平均薪資升序排列 4 select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) 5 # 3. 查詢各崗位平均薪資大於10000的崗位名、平均工資,結果按平均薪資降序排列 6 select post,avg(salary) from employee group by post having avg(salary) > 10000 order by avg(salary) desc;練習:order by
5、.limit 限制查詢的條數
limit m,n m代表從第幾條搜尋資料 , n 代表搜尋幾條 m=0 代表搜尋第一條資料
# 分頁 select * from employee limit 0,10 # 0代表第一條 ,往後搜10條資料 select * from employee limit 10,10 # 10代表第11條,往後搜10條資料 select * from employee limit 20,10 # 20代表第21條,往後搜10條資料
# limit 數字 代表搜尋條數 select * from employee limit 1; # 搜尋表裡面最後一條資料 select * from employee order by id desc limit 1; # 搜尋表裡面最後三條資料 select * from employee order by id desc limit 3;
6、(瞭解) 可以使用正則表示式 (不推薦使用)
select * from employee where emp_name regexp ".*n$"; #?號不識別 select * from employee where emp_name regexp "程咬.*";
二、多表查詢
1 #建表 2 create table department( 3 id int, 4 name varchar(20) 5 ); 6 7 create table employee( 8 id int primary key auto_increment, 9 name varchar(20), 10 sex enum('male','female') not null default 'male', 11 age int, 12 dep_id int 13 ); 14 15 #插入資料 16 insert into department values 17 (200,'技術'), 18 (201,'人力資源'), 19 (202,'銷售'), 20 (203,'運營'); 21 22 insert into employee(name,sex,age,dep_id) values 23 ('egon','male',18,200), 24 ('alex','female',48,201), 25 ('wupeiqi','male',38,201), 26 ('yuanhao','female',28,202), 27 ('liwenzhou','male',18,200), 28 ('jingliyang','female',18,204) 29 ;建兩張表
1、內聯查詢(內聯接)
inner join 至少兩表以上做查詢,把滿足條件的所有資料查詢出來(查詢的是共同擁有的資料)
- select 欄位 from 表1 inner join 表2 on 必要的關聯欄位 (2張表)
- select 欄位 from 表1 inner join 表2 on 必要的關聯欄位1 inner join 表3 on 必要的關聯欄位2 ... 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 寫法預設等價於inner join 也是內聯查詢 select * from employee , department where employee.dep_id = department.id ; select * from employee as e, department as d where e.dep_id = d.id ;
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、全聯查詢(全聯接) left join + right join
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 ;
三、子查詢
子查詢 : sql語句的巢狀
(1) sql語句當中巢狀另外一條sql,用括號()包起來,表達一個整體;
(2) 一般用在子句的後面 比如from , where ...身後 表達一個條件或者一張表
(3) 速度快慢 : 單表查詢 > 聯表查詢 > 子查詢
1 #建表 2 create table department( 3 id int, 4 name varchar(20) 5 ); 6 7 create table employee( 8 id int primary key auto_increment, 9 name varchar(20), 10 sex enum('male','female') not null default 'male', 11 age int, 12 dep_id int 13 ); 14 15 #插入資料 16 insert into department values 17 (200,'技術'), 18 (201,'人力資源'), 19 (202,'銷售'), 20 (203,'運營'); 21 22 insert into employee(name,sex,age,dep_id) values 23 ('egon','male',18,200), 24 ('alex','female',48,201), 25 ('wupeiqi','male',38,201), 26 ('yuanhao','female',28,202), 27 ('liwenzhou','male',18,200), 28 ('jingliyang','female',18,204) 29 ;建立兩張表
1、基本用法
1、找出平均年齡大於25歲以上的部門
# where select department.id,department.name from employee,department where employee.dep_id = department.id group by department.id,department.name having avg(age) > 25;
# 用as 起別名 select d.id,d.name from employee as e,department as d where e.dep_id = d.id group by d.id,d.name having avg(age) > 25;
# inner join select d.id,d.name from employee as e inner join department as d on e.dep_id = d.id group by d.id,d.name having avg(age) > 25;
2、子查詢練習
1.找平均年齡大於25歲以上的部門id
select dep_id from employee group by employee.dep_id having avg(age) > 25 # 2.通過id上 department 表裡面找部門名 select name from department where id in(201,202); # 3.綜合拼接 select id,name from department where id in(select dep_id from employee group by employee.dep_id having avg(age) > 25);
2.檢視技術部門員工姓名
1 # where 2 select 3 e.name 4 from 5 employee as e , department as d 6 where 7 e.dep_id = d.id 8 and 9 d.name = "技術" 10 11 # inner join 12 select 13 e.name 14 from 15 employee as e inner join department as d on e.dep_id = d.id 16 where 17 d.name = "技術" 18 19 20 # 子查詢 21 # (1) 通過技術部門找id 22 select id from department where name = "技術" 23 # (2) 通過id 找員工姓名 24 select name from employee where dep_id = 200; 25 # (3) 綜合拼接 26 select name from employee where dep_id = (select id from department where name = "技術");View Code
3.檢視哪個部門沒員工
1 # 聯表查詢 2 select 3 d.id,d.name 4 from 5 department as d left join employee as e on d.id = e.dep_id 6 where 7 e.id is null 8 9 # 子查詢 10 # 1.找員工都在哪些部門 11 select dep_id from employee group by dep_id 12 13 # 2把不在該部門的員工找出來 14 select id from department where id not in (200,201,202,204); 15 16 # 綜合拼接 17 select id , name from department where id not in (select dep_id from employee group by dep_id);View Code
4.查詢大於平均年齡的員工名與年齡
1 select name , age from employee where age > 28 2 # 計算平均年齡 3 select avg(age) from employee; 4 # 綜合拼接 5 select name , age from employee where age > (select avg(age) from employee);View Code
5.把大於其本部門平均年齡的員工名和姓名查出來
1 # 1.先計算本部門的平均年齡是多少 2 select dep_id,avg(age) from employee group by dep_id 3 # 2.把搜尋出來的資料和employee表進行聯表,最後做單表查詢 4 select 5 * 6 from 7 employee as t1 inner join (1號sql查詢出來的資料) as t2 on t1.dep_id = t2.dep_id 8 9 # 3.綜合拼接 10 select 11 * 12 from 13 employee as t1 inner join (select dep_id,avg(age) from employee group by dep_id) as t2 on t1.dep_id = t2.dep_id 14 15 # 4.做單表查詢 16 select 17 t1.name 18 from 19 employee as t1 inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t2 on t1.dep_id = t2.dep_id 20 where 21 t1.age > t2.avg_ageView Code
6.查詢每個部門最新入職的那位員工 # 利用上一套資料表進行查詢;
1 # 1.找每個部門 hire_date 欄位的最大值(即是最新入職的員工) 2 select max(hire_date) as max_date , post from employee group by post 3 # 2.把 employee 和 子查詢搜出的最大日期做聯表,合併成大表之後,在做單表查詢; 4 select 5 * 6 from 7 employee as t1 inner join (1號查詢出來的資料) as t2 on t1.post = t2.post 8 9 # 3.綜合拼接 10 select 11 * 12 from 13 employee as t1 inner join (select max(hire_date) as max_date , post from employee group by post) as t2 on t1.post = t2.post 14 15 # 4.最後做單表查詢 16 select 17 t1.emp_name,t1.hire_date 18 from 19 employee as t1 inner join (select max(hire_date) as max_date , post from employee group by post) as t2 on t1.post = t2.post 20 where 21 t1.hire_date = t2.max_dateView Code
7 總結:
子查詢可以作為臨時表,也可以作為where子句的條件,通過()包括sql,表達一個整體;
一般用在各個子句後面 select .. from ... where ...
思路:
可以把臨時搜尋出來的資料變成臨時表,在和其他表做聯表,最後做單表查詢;
3.帶EXISTS關鍵字的子查詢
exists 關鍵字,表達資料是否存在,用在子查詢裡
如果內層sql 能夠查到資料,返回True ,外層sql執行sql語句
如果內層sql 不能夠查到資料,返回False ,外層sql不執行sql語句
select * from employee where exists (select * from employee where id = 1); select * from employee where exists (select * from employee where id = 100);