1. 程式人生 > 實用技巧 >MySql的用法總結-2

MySql的用法總結-2

本節內容:

  一、單表查詢

    1.1、where 條件的使用

    1.2、 group by 子句 分類,分組

    1.3、 having 應用

    1.4order by 排序

    1.5limit 限制查詢的條數

    1.6 正則使用(瞭解)

  二、多表查詢

    2.1內聯查詢(內聯接)

    2.2外聯查詢(外聯接)

    2.3全聯查詢(全聯接)

  三、子查詢

    3.1 基本用法

    3.2 子查詢練習

    3.3帶EXISTS關鍵字的子查詢

一、 單標查詢

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_age
View 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_date
View 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);