MySQL基礎(三):SQL查詢語句中的關鍵字講解、多表連接操作

下面是小凰凰的簡介,看下吧!
💗人生態度:珍惜時間,渴望學習,熱愛音樂,把握命運,享受生活
💗學習技能:網絡 -> 雲計算運維 -> python全棧( 當前正在學習中)
💗您的點贊、收藏、關注是對博主創作的最大鼓勵,在此謝過!
有相關技能問題可以寫在下方評論區,我們一起學習,一起進步。
後期會不斷更新python全棧學習筆記,秉着質量博文爲原則,寫好每一篇博文。

1、幾個重要關鍵字的執行順序

# 書寫順序
select id,name from emp where id > 3;
# 執行順序
from -> where -> select

溫馨提示:當一個查詢的一個表的字段非常大時,可以使用\G分行展示!

select * from emp\G;

2、where過濾

# 作用:是對整體數據的篩選
select id,name from emp where id between 3 and 6; # 3 =< id <= 6。拓展:not between
select * from emp where salary in (20000,15000,10000); # 薪水在三者之中。拓展:not in

# 模糊查詢(%代表匹配任意多個字符,_匹配任意單個字符)
select name,salary from emp where name like '%o%';

# 查詢員工姓名是由四個字符組成的姓名和薪資
select name,salary from emp where name like '____'; # 也可以使用char_length(name)=4

# 查詢崗位描述爲空的員工姓名和崗位名 針對null不用等號 用is
select * from emp where salary is null; # 拓展:is not null

3、group by分組、as別名

(1)group by分組、聚合函數
# 分組實際應用場景
	男女比例
	部門平均工資
	國家之間數據統計
	...
'注意:'分組之後,最小可操作單位是組。不能直接獲取組內的單條數據,後續有方法可以實現。

# 什麼時候需要分組?
遇到關鍵字:每個、平均、最高、最低

# 實戰:
1. 獲取每個部門的最高薪資
select post,max(salary) from emp group by post;
select post as '部門',max(salary) as '最高薪資' from emp group by post; # as起別名
==========其他用法===========
最低:min()
平均:avg()
總和:sum()
注:和max使用一樣

2. 統計每個部門的人數
select count(id) from emp group by post;
'注意:count的所傳的字段必須是not null'
除此之外,可以使用任一字段作爲count的計數依據,一般我們選擇比較代表性的,比如部門的人數,就可以用獨一無二的工號來計數。
(2)as別名

as給字段起別名

select name as '姓名',salary*12 as '年薪' from emp;

as給表起別名

select t1.id,t1.name from emp as t1; # 因爲先執行from,因此emp表就變成了t1表,因此select需要是t1,主要是解決表名過長的問題輸入麻煩,
(3)分組注意事項
1. 關鍵字wheregroup by同時出現時,group by必須在where後面。
2. where先對整體數據進行過濾,之後再進行分組,聚合函數只能在分組之後使用,不能在where中使用!
3. select max(salary) from emp;上面說只能在分組之後使用,那麼這個句子是錯誤的吧!不,它是正確的。'因爲默認整體就是一組!'

# 統計各部門年齡在30歲以上的員工的平均薪資
select post,avg(salary) from emp where age > 30 group by post; 

4、group_concat與concat

(1)group_concat

我們前面說了分組後無法直接查詢某個數據,操作都是以組爲單位!因此我們需要通過group_concat間接查詢!

# 查詢每個部門下有哪些人
select dpm_id,group_concat(stuff_name) from stuff group by dpm_id;

在這裏插入圖片描述上面還只是一個簡單應用,牛逼操作如下:
它支持拼接操作:

select dpm_id as '部門號',group_concat(stuff_name,':',stuff_age) as '員工信息' from stuff group by dpm_id;

在這裏插入圖片描述

(2)concat
select concat(stuff_name,'_DSB') from stuff where stuff_id != 1;

在這裏插入圖片描述

(3)concat與group_concat的區別
有分組時用group_concat,沒有分組用concat

5、having分組之後篩選

having的語法跟where是一樣的,且它們都是用來過濾的。
只不過having是用於分組之後的過濾,因爲在分組之後,所以支持聚合函數!

# 統計各部門年齡在30歲以上的員工工資並且保留平均薪資大於一萬的部門
select post,avg(salary) from emp
where age > 30
group by post
having avg(salary) > 10000
;

6、distinct去重

一定要注意,必須是完全一樣的數據,才能去重。

{'id':1,'name':'hehe','age'=18}
{'id':2,'name':'hehe','age'=18}
{'id':3,'name':'haha','age'=20}
# 從上面我們可以看出第一個和第二個重複了嗎?沒有重複!
因爲12的id不同,但是在生產環境中,一般這個id是設置爲自增的,'很有可能忽視id',只對比了name、age,這樣看就是相同的,最後發現這兩個數據怎麼也去重不了。
select distinct name,age from emp; # 針對上述問題,需要這樣去重,有點聯合唯一的感jio!
select distinct age from emp; # 去重可以隨意指定字段的多少。

7、order by排序

# 基礎
select * from emp order by salary asc; # 默認採用升序,asc可以省略
select * from emp order by salary desc; # 降序
# 進階
先按照age降序排,如果碰到age相同,再按照salary升序排
select * from emp order by age desc,salary asc; # salary後面還可以加,應付salary相同的情況!

8、limit限制限制展示條數

針對數據過多的情況,我們都是做分頁處理!

select * from emp limit 3; # 只展示三條數據
select * from emp limit 0,5; # 只展示從第一條數據開始的五條數據
select * from emp limit 5,5; # 只展示從第六條數據開始的五條數據
第一個參數是起始位置
第二個參數是展示條數

在這裏插入圖片描述在這裏插入圖片描述

9、正則

select * from emp where name regexp '^j.*(n|y)$';

在這裏插入圖片描述

10、連表操作

create table dpm( # 創建部門表
dpm_id int primary key auto_increment,
dpm_name varchar(20) not null unique 
);

create table stuff( # 創建員工表
stuff_id int primary key auto_increment,
stuff_name varchar(20) not null unique,
stuff_age int not null,
stuff_gender enum('male','female'),
dpm_id int not null,
foreign key(dpm_id) references dpm(dpm_id)
on delete cascade
on update cascade
);

insert into dpm(dpm_name) values ('運維部'), ('技術部'), ('測試部'), ('財務部'), ('售後部');
MariaDB [db1]> select * from dpm;
+--------+-----------+
| dpm_id | dpm_name  |
+--------+-----------+
|      5 | 售後部    |
|      2 | 技術部    |
|      3 | 測試部    |
|      4 | 財務部    |
|      1 | 運維部    |
+--------+-----------+

insert into stuff(stuff_name,stuff_age,stuff_gender,dpm_id) values ('吳晉丞',18,'male',1),('徐浩波',80,'male',2),('李丹',30,'female',4),('陳果',18,'male',5),('李青松',18,'male',3),('鄧小龍',30,'male',5),('陳媛媛',21,'female',4);
MariaDB [db1]> select * from stuff;
+----------+------------+-----------+--------------+--------+
| stuff_id | stuff_name | stuff_age | stuff_gender | dpm_id |
+----------+------------+-----------+--------------+--------+
|        1 | 吳晉丞     |        18 | male         |      1 |
|        2 | 徐浩波     |        80 | male         |      2 |
|        3 | 李丹       |        18 | female       |      4 |
|        4 | 陳果       |        18 | male         |      5 |
|        5 | 李青松     |        18 | male         |      3 |
|        6 | 鄧小龍     |        30 | male         |      5 |
|        7 | 陳媛媛     |        21 | female       |      4 |
+----------+------------+-----------+--------------+--------+

查詢平均年齡大於20歲的部門:
多表查詢有兩種方法可以解決:

(1)聯表操作
select dpm_name from stuff inner join dpm
on stuff.dpm_id = dpm.dpm_id
group by dpm_name
having avg(stuff_age) > 20;

# 結果
+-----------+
| dpm_name  |
+-----------+
| 售後部    |
| 技術部    |
+-----------+
(2)子查詢
select dpm_name from dpm where dpm_id in
(select dpm_id from stuff group by dpm_id
having avg(stuff_age) > 20);

# 結果:
+-----------+
| dpm_name  |
+-----------+
| 售後部    |
| 技術部    |
+-----------+
(3)內連接、左連接、右連接區別

還有一個union(全連接)就是左連接和右連接的並集,幾乎很少用,故不講!

  • inner join(內連接)產生的結果是AB的交集(不會有null出現):

在這裏插入圖片描述

  • A left join B (左連接)產生表A的完全集,而表B中匹配的則有值,沒有匹配的則以null值取代.

在這裏插入圖片描述左連接,就是從A表看起走,如果外鍵不爲空,則有值,外鍵如果爲空,那麼dpm中就用null表示因爲我這裏限制了stuff中的dpm_id不爲空,因此這裏的結果永遠都和等值連接的結果一樣!

  • A left join B (右連接)產生表B的完全集,而表A中匹配的則有值,沒有匹配的則以null值取代

在這裏插入圖片描述售前部沒有人,因此dpm產生完全集,stuff中沒有匹配的員工,因此全用null取代!
右連接就是,從B表看起走,通過被外鍵約束的dpm_id,找有沒有相應的員工,沒有則,null值代替。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章