基本查詢語句及方法
執行順序:
from
where
group by
having
distinct
order by
limit
....
連表
inner join
left join
right join
union
子查詢
書寫順序
select id,name from emp where id > 3 and id < 6;
執行順序
from # 確定到底是哪站表
where # 根據過來條件 篩選數據
select # 拿出篩選出來的數據中的某些字段
select * from emp\G; 當表字段特別多的時候 結果的排版可能會出現混亂的現象 你可以在查詢語句加\G來規范查詢結果
# 1.查詢id大於等於3小於等於6的數據
select * from emp where id >= 3 and id <= 6;
select * from emp where id between 3 and 6;
上述語句完全等價
# 2.查詢薪資是20000或者18000或者17000的數據
select id,name from emp where salary = 20000 or salary = 18000 or salary = 17000;
select id,name from emp where salary in (20000,18000,17000);
# 3.查詢員工姓名中包含o字母的員工姓名和薪資
模糊匹配 like
%:匹配多個任意字符
_:匹配一個任意字符
select name,salary from emp where name like '%o%';
# 4.查詢員工姓名是由四個字符組成的員工姓名與其薪資
select name,salary from emp where name like '____';
# 5.查詢id小於3或者大於6的數據
select * from emp where id < 3 or id > 6;
select * from emp where id not between 3 and 6;
# 6.查詢薪資不在20000,18000,17000范圍的數據
select id,name from emp where salary not in (20000,18000,17000);
# 7.查詢崗位描述為空的員工名與崗位名 針對null判斷的時候只能用is 不能用=
select name,post from emp where post_comment = Null;
select name,post from emp where post_comment is Null;
MySQL對大小寫不敏感
group by 分組
# 1.按部門分組
select * from emp group by post;
分組之后應該做到最小單位是組,而不應該再展示組內的單個數據信息
MySQL中分組之后 只能拿到分組的字段信息 無法直接獲取其他字段信息
但是你可以通過其他方法(聚合函數)簡介的獲取
如果你的MySQL不報錯 說明嚴格模式沒有設置
show variables like '%mode%';
set session 當前窗口有效
set global 全局有效
set global sql_mode="strict_trans_tables,only_full_group_by";(設置嚴格模式)
select * from emp group by post;
select id,name from emp group by post;
select name from emp group by post;
# 2.獲取每個部門的最高工資 聚合函數 max min avg sum count
select post,max(salary) from emp group by post;
給字段取別名
select post as '部門',max(salary) as '最高工資' from emp group by post;
select post '部門',max(salary) '最高工資' from emp group by post;
# 每個部門的最低工資
select post,min(salary) from emp group by post;
# 每個部門的平均工資
select post,avg(salary) from emp group by post;
# 每個部門的工資總和
select post,sum(salary) from emp group by post;
# 每個部門的人數
select post,count(age) from emp group by post;
select post,count(salary) from emp group by post;
select post,count(id) from emp group by post;
select post,count(post_comment) from emp group by post;
在統計分組內個數的時候 填寫任意非空字段都可以完成計數,推薦使用能夠唯一標識數據的字段
比如id字段
"""
聚合函數會自動將每一個分組內的單個數據做想要的計算,無需你考慮
"""
# 3.查詢分組之后的部門名稱和每個部門下所有的學生姓名
select post,group_concat(name) from emp group by post;
select post,group_concat('DSB',name) from emp group by post;
group_concat()能夠拿到分組后每一個數據指定字段(可以是多個)對應的值
select post,group_concat(name,": ",salary) from emp group by post;
concat
select concat("NAME: ",name),concat("SAL: ",salary) from emp;
小技巧:
concat就是用來幫你拼接數據
concat 不分組情況下使用
group_concat 分組之后使用
# 查詢每個員工的年薪
select name,salary*12 from emp;
# 剛開始查詢表,一定要按照最基本的步驟,先確定是哪張表,再確定查這張表也沒有限制條件,再確定是否需要分類,最后再確定需要什么字段對應的信息
"""
你應該將每一步操作產生的結果都當成是一張新的表
然后基於該表再進行其他的操作
"""
1. 查詢崗位名以及崗位包含的所有員工名字
select post as 部門名稱,group_concat(name)as 部門成員 from emp group by post;
2. 查詢崗位名以及各崗位內包含的員工個數
select post,count(id) from emp group by post;
3. 查詢公司內男員工和女員工的個數
select sex,count(id)from emp group by sex;
4. 查詢崗位名以及各崗位的平均薪資
select post as 崗位,avg(salary) as 平均薪資 from emp group by post;
5. 查詢崗位名以及各崗位的最高薪資
select post as 崗位,max(salary) as 最高薪資 from emp group by post;
6. 查詢崗位名以及各崗位的最低薪資
select post as 崗位,min(salary) as 最低薪資 from emp group by post;
7. 查詢男員工與男員工的平均薪資,女員工與女員工的平均薪資
select sex as 性別,avg(salary) as 平均薪資 from emp group by sex;
"""
聚合函數
max min sum count avg只能在分組之后使用
如果一張表沒有寫group by默認所有的數據就是一組
"""
書寫順序
select
from
where
group by
執行順序
from
where
group by
select
8、統計各部門年齡在30歲以上的員工平均工資
# 先獲取年齡在30歲以上的員工
select post,avg(salary) from emp where age > 30 group by post;
"""
寫sql語句的時候 一定不要一口氣寫完
前期先按照步驟一步步寫
寫一步查詢看一下結果然后基於當前結果再往后寫
"""
having
跟where是一模一樣的 也是用來篩選數據
但是having是跟在group by之后的
where是對整體數據做一個初步的篩選
而having是對分組之后的數據再進行一次針對性的篩選
1、統計各部門年齡在30歲以上的員工平均工資,
並且保留平均工資大於10000的部門
select post,avg(salary) from emp where age > 30 group by post having avg(salary) > 10000;
select post,avg(salary) from emp where age > 30 group by post where avg(salary) > 10000; # 報錯
# 強調:having必須在group by后面使用
select * from emp having avg(salary) > 10000; # 報錯
執行順序
from
where
group by
having
select
distinct去重
多重復的數據進行一個去重
"""
去重必須數據是一模一樣的才能去重
只要有一個不一樣 都不能算是的重復的數據
"""
select distinct id,age from emp;
執行順序
from
where
group by
having
select
distinct
order by 排序
默認是升序 asc
也可以變成降序 desc
select * from emp order by salary;
select * from emp order by salary asc;
select * from emp order by salary desc;
select * from emp order by age,salary; # 先按照age做升序 age相同的情況下再按照salary做升序
select * from emp order by age asc,salary desc; # 先按照age做升序 age相同的情況下再按照salary做升序
# 統計各部門年齡在10歲以上的員工平均工資,
# 並且保留平均工資大於1000的部門,然后對平均工資進行排序
select post,avg(salary) from emp where age > 10 group by post having avg(salary) > 1000 order by avg(salary);
limit 限制展示數據的條數
select * from emp limit 5; # 只展示數據的五條
select * from emp limit 5,5; #從第六條開始展示五條
"""
當limit只有一個參數的時候 表示的是只展示幾條
當limit有兩個參數的時候 第一個參數表示的起始位置 第二個參數表示從起始位置開始往后展示的條數
"""
# 查詢工資最高的人的詳細信息
# 先按照薪資排序
# 再用limit限制 只取一條
select * from emp order by salary desc limit 1;
# 在編程中 只要看到reg開頭的 基本上都是跟正則相關
正則
select * from emp where name regexp '^j.*(n|y)$'; # 表示統計以j開頭n或y結尾中間是0個或多個任意字符的字符串。
jason
jssdsdsay
jy
jnn
多表查詢
"""
表查詢分為兩大類
1.聯表查詢
2.子查詢
"""
select * from emp,dep; 產生的結果是一個笛卡爾積
# 查詢部門為技術部的員工及部門信息
# 多表查詢
表創建
```mysql
#建表
create table dep(
id int,
name varchar(20)
);
create table emp(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') not null default 'male',
age int,
dep_id int
);
#插入數據
insert into dep values
(200,'技術'),
(201,'人力資源'),
(202,'銷售'),
(203,'運營');
insert into emp(name,sex,age,dep_id) values
('jason','male',18,200),
('egon','female',48,201),
('kevin','male',38,201),
('nick','female',28,202),
('owen','male',18,200),
('jerry','female',18,204)
;
# 當初為什么我們要分表,就是為了方便管理,在硬盤上確實是多張表,但是到了內存中我們應該把他們再拼成一張表進行查詢才合理
```
表查詢
```mysql
select * from emp,dep; # 左表一條記錄與右表所有記錄都對應一遍>>>笛卡爾積
# 將所有的數據都對應了一遍,雖然不合理但是其中有合理的數據,現在我們需要做的就是找出合理的數據
# 查詢員工及所在部門的信息
select * from emp,dep where emp.dep_id = dep.id;
# 查詢部門為技術部的員工及部門信息
select * from emp,dep where emp.dep_id = dep.id and dep.name = '技術';
# 將兩張表關聯到一起的操作,有專門對應的方法
# 1、內連接:只取兩張表有對應關系的記錄
select * from emp inner join dep on emp.dep_id = dep.id;
select * from emp inner join dep on emp.dep_id = dep.id
where dep.name = "技術";
# 2、左連接: 在內連接的基礎上保留左表沒有對應關系的記錄
select * from emp left join dep on emp.dep_id = dep.id;
# 3、右連接: 在內連接的基礎上保留右表沒有對應關系的記錄
select * from emp right join dep on emp.dep_id = dep.id;
# 4、全連接:在內連接的基礎上保留左、右面表沒有對應關系的的記錄
select * from emp left join dep on emp.dep_id = dep.id
union
select * from emp right join dep on emp.dep_id = dep.id;
```
有專門幫你做連表的方法
內連接(inner join)
左連接(left join)
右連接(right join)
全連接(union) # 只要將左連接和右連接的sql語句 加一個union就變成全連接
select * from emp left join dep on emp.dep_id = dep.id
union
select * from emp right join dep on emp.dep_id = dep.id;
子查詢
將一張表的查詢結果作為另外一個sql語句的查詢條件
select name from dep where id = (select dep_id from emp where name = 'jason');
# 2.每個部門最新入職的員工
# 思路:先查每個部門最新入職的員工,再按部門對應上聯表查詢
select t1.id,t1.name,t1.hire_date,t1.post,t2.* from emp as t1
inner join
(select post,max(hire_date) as max_date from emp group by post) as t2
on t1.post = t2.post
where t1.hire_date = t2.max_date
;
# 子查詢
```mysql
# 就是將一個查詢語句的結果用括號括起來當作另外一個查詢語句的條件去用
# 1.查詢部門是技術或者人力資源的員工信息
"""
先獲取技術部和人力資源部的id號,再去員工表里面根據前面的id篩選出符合要求的員工信息
"""
select * from emp where dep_id in (select id from dep where name = "技術" or name = "人力資源");
# 2.每個部門最新入職的員工 思路:先查每個部門最新入職的員工,再按部門對應上聯表查詢
select t1.id,t1.name,t1.hire_date,t1.post,t2.* from emp as t1
inner join
(select post,max(hire_date) as max_date from emp group by post) as t2
on t1.post = t2.post
where t1.hire_date = t2.max_date
;
"""
記住一個規律,表的查詢結果可以作為其他表的查詢條件,也可以通過其別名的方式把它作為一張虛擬表去跟其他表做關聯查詢
"""
select * from emp inner join dep on emp.dep_id = dep.id;
# 可以給表起別名
# 可以給查詢出來的虛擬表起別名
# 可以給字段起別名