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