個人主頁:顧漂亮
目錄
1.CRUD簡介
2.Create新增
使用示例:
注意點:
3.Retrieve檢索
使用示例:
注意點:
4.where條件查詢
前置知識:-- 運算符
比較運算符
使用示例:?
注意點:
5.Order by 排序
使用示例:
注意點:
6.分頁查詢
使用示例:
注意點:
7.Update修改
使用示例:
注意點:
8.Delete刪除
使用示例:
注意點:
9.截斷表
使用示例:
注意點:
10.插入查詢結果
使用示例:
注意點:
11.聚合函數
常見聚合函數:
12.group by分組查詢
使用示例:
注意點:
?
1.CRUD簡介
Create(創建)
Retrieve(讀取)
Update(更新)
Delete(刪除)
2.Create新增
使用示例:
use ghr;
-- create新增
drop table if exists users; -- 在創建之前添加一層校驗
create table users(id bigint primary key auto_increment, -- 為id列設置自增主鍵name varchar(20) not null -- 為name列設置不為空條件
);-- 顯示表 -- 使用該語句前必須先使用use 語句,進入一個數據庫中!!!!
show tables;-- 單行數據全插入 values 中的數據順序必須要與列的順序一致
insert into users values (1, '張三'); -- 注意:MySQL中的字符串需要用單引號包裹-- 單行數據指定列插入 -- values中的數據 必須要與users后面括號中的順序一致
insert into users(id, name) values (3, '王五'); -- 多行數據指定列插入 多個數據中間用 , 分開即可
insert into users(id, name) values (4, '趙六'), (5, '錢七');select * from users;
注意點:
-
一次插入一條數據的效率高還是一次插入多條數據的效率更高?
-
執行所有的SQL語句都會有網絡開銷
-
MySQL數據庫在保存數據的時候也會有磁盤開銷
-
每執行一條SQL語句都需要開啟一個事務,事務的開啟到關閉也需要消耗資源
-
因此:一次提交多條數據在一個可控范圍內的時候,比一次提交一次數據的效率可以高一點!!
3.Retrieve檢索
使用示例:
-- 檢索查詢
use ghr; -- 使用ghr數據庫-- 首先創建表
drop table if exists exam; -- 添加校驗
create table exam(id bigint primary key auto_increment,name varchar(20) not null, chinese float,math float,english float
);-- 插入測試數據insert into exam(id, name, chinese, math, english) values
(1, '唐三藏', 67, 98, 56),(2, '孫悟空', 87, 78, 77),(3, '豬悟能', 88, 98, 90),(4, '曹孟德', 82, 84, 67),(5, '劉玄德', 55, 85, 45),(6, '孫權', 70, 73, 78),(7, '宋公明', 75, 65, 30);-- 全列查詢select * from exam;-- 指定列查詢select name, chinese from exam;
select chinese, name from exam; -- 要查詢的列只要在表中存在,與順序無關-- 查詢字段為表達式
# 把所有語文成績+10
select id, name, chinese+10 as sum from exam; -- 可以為表達式起一個別名 可以加 as 不加也可以
# 計算總成績
select id, name, chinese + math + english as 總分 from exam;-- 為結果去重查詢
select distinct math from exam;
注意點:
-
用
select
返回的查詢結果是根據查詢列表中字段和表達式生成的一個臨時表,并不會真正修改數據表中的值 -
在
select
后面的查詢列表中指定希望查詢的列,可以是一個也可以是多個,中間用逗號隔開。指定列的順序與表的結構無關 -
使用
disctinct
去重時候,只有查詢列表中所有列的值相同的時候才會判定為重復 -
查詢不加限制條件會返回表中的所有結果,如果表中的數據量過大,會把服務器的資源消耗殆盡
-
在生產環境下,一定注意謹慎使用不加限制條件的查詢
4.where條件查詢
前置知識:-- 運算符
比較運算符
運算符 | 說明 |
---|---|
>,>=,<, <= | 與Java/c等用法相同 |
= | 等于,對于NULL的比較不安全,比如NULL = NULL的結果還是NULL |
<=> | 等于,對于NULL的比較是安全的, 比如NULL <=> NULL 結果為1 |
!=, <> | 不等于 |
Between A and B | 匹配范圍[A,B] |
Value in(A, B, ....) | 如果value在in中返回1,不再返回0 |
Is null | 判斷是NULL |
Is not null | 判斷不是NULL |
like | 模糊匹配 |
運算符 | 說明 |
---|---|
or | 任意一個條件 |
and | 多個條件必須同時成立 |
not | 類似于!取反操作 |
使用示例:?
-- where條件查詢use ghr;-- 基本查詢
# 英語成績小于60
select name, english from exam where english <= 60;
# 總成績200分以下 -- 注意where語句中不可以使用別名
select name, chinese+math+english as 總分 from exam where chinese + math+english < 200;-- and和or 優先級 -- not > and > as 如果三者混合使用,建議加()
select * from exam where chinese > 80 and english > 80;select * from exam where chinese > 80 or english > 80;-- 范圍查詢select name, chinese from exam where chinese between 80 and 90;select name, math from exam where math in(78, 79, 98, 99);-- 模糊查詢select * from exam where name like '孫%';
# 注意二者區別
select * from exam where name like '孫_';-- NULL的查詢
# 構造數據
insert into exam values (8, '張飛', 27, 0, NULL);select * from exam where english is null;select * from exam where english is not null;# NULL 值與其他值運算結果為NULL
select name, chinese + math + english as sum from exam;
注意點:
-
where
條件中可以使用表達式,但是不能使用別名 -
and
優先級高于or
,在同時使用的時候,建議使用小括號包裹優先執行的部分 -
NULL
與任何值運算結果都為NULL
-
過濾
NULL
時不要使用=,!=,<>
5.Order by
排序
使用示例:
-- 前置知識:asc 為升序 desc為降序-- 按照英語成績降序
select name, english from exam order by english desc;-- 查詢總分,從高到低
select name, chinese + math + english as 總分 from exam order by 總分 desc; # 可以使用別名進行查詢-- 去除有NULL值的排序
-- 所有英語成績不為NULL的同學,按照語文成績從高到低
select name, chinese, math, english from exam where english is not null order by chinese desc;
注意點:
-
查詢中若沒有
oder by
子句,返回的順序是未定義的,永遠不要依賴這個順序 -
Order by
子句中可以使用列的別名進行排序,注意與where
進行區分 -
NULL
進行排序的時候,視為比任何值都小,升序出現在最上面,降序出現在最下面
6.分頁查詢
使用示例:
-- 分頁查詢 -- 三種方案,以下三種方案查詢結果都是相同的select * from exam order by id asc limit 3; -- 默認從偏移量0位置開始,查詢3行數據select * from exam order by id asc limit 0,3; -- 從偏移量0位置開始查詢,查詢3條數據select * from exam order by id asc limit 3 offset 0;-- 從偏移量0位置開始查詢,查詢3條數據
注意點:
-
分頁查詢可以有效控制一次返回的記錄條數
-
可以有效減少數據庫服務器的壓力,同時對于用戶也比較友好
-
在工作中,一定注意多使用分頁查詢
7.Update修改
使用示例:
-- 將孫悟空同學數學成績變為80update exam set math=80 where name='孫悟空';-- 將總成績倒數前3的數學成績加上5分# 先查看原始數據
select name, chinese+math+english as sum from exam where chinese+math+english is not null order by sum asc limit 3;# 注意 where語句中不可以隨意起別名
-- 錯誤示范select name, chinese+math+english from exam where chinese+math+english as sum is not null order by sum asc limit 3;
update exam set math=math+5 where chinese + math + english is not null order by chinese + math + english asc limit 3;# 查看查詢結果
select name, chinese+math+english as sum from exam where name in ('宋公明', '劉玄德', '唐三藏') order by sum asc;
注意點:
-
在原值的基礎上做變更時,不能使用
math+=30
這樣的語法 -
不加
where
條件時,會導致全表數據被更新,謹慎操作 -
一般情況下類似于這樣的更新
update exam set math=80 where name='孫悟空';
最為合適,先用where
語句過濾,再進行更新
8.Delete刪除
使用示例:
-- 刪除表中一項數據
# 刪除表中孫悟空的成績
delete from exam where name = '孫悟空';-- 刪除整張表的數據
# 準備一個測試表作為備份
create table if not exists t_delete(id int,name varchar(20)
);
# 插入被測數據
insert into t_delete(id,name) values (1, 'A'), (2, 'B'), (3, 'C');#刪除表格中的數據
delete from t_delete;
注意點:
-
如果執行
delete
操作不加限制條件,會將整個表中的數據全部刪除,謹慎使用 -
MySQL服務如果開啟了二進制日志,每一次的
insert、update、delete
操作都會記錄在二進制日志里,如果需要恢復數據,可以讀取日志中的記錄,再進行反操作即可、 -
注意
delete
只是刪除表中的數據,并不會刪除表,刪除表需要用到表的操作中的drop
,注意不要搞混淆
9.截斷表
使用示例:
-- 創建測試表
# 檢查判斷
drop table if exists t_truncate;
create table t_truncate(id bigint primary key auto_increment,name varchar(20)
);# 插入測試數據
insert into t_truncate(name) values ('A'), ('B'), ('C');-- 顯示建表結構 -- 以下是在命令行窗口中進行 AUTO_INCREMENT=4
mysql> show create table t_truncate;
+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_truncate | CREATE TABLE `t_truncate` (`id` bigint NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)-- 截斷表
mysql> truncate table t_truncate;
Query OK, 0 rows affected (0.03 sec)
-- 顯示截斷后表的結構 發現AUTO_INCREMENT 被重置為0
mysql> show create table t_truncate;
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table|
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_truncate | CREATE TABLE `t_truncate` (`id` bigint NOT NULL AUTO_INCREMENT,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-- 繼續寫入數據 AUTO_INCREMENT為1
insert into t_truncate(name) values('d');
注意點:
-
只能對整表操作,不能像
delete
一樣對部分數據刪除 -
執行
truncate
操作時會把表的狀態重置為初始狀態,表中的數據也會被清除 -
執行
truncate
不對數據操作所以比delete
更快,truncate
在刪除數據的時候,不經過真正的事務,所以無法回滾 -
會重置
auto_increment
項
10.插入查詢結果
使用示例:
-- 刪除表中的重復數據
#首先創建測試表
drop table if exists t_record;
create table t_record(id int,name varchar(20)
);#插入測試數據
insert into t_record(id,name) values
(100, 'aaa'),
(100, 'aaa'),
(200, 'bbb'),
(200, 'bbb'),
(200, 'bbb'),
(300, 'ccc');# 創建一張新表,表結構與t_record相同
drop table if exists t_record_new;
create table t_record_new like t_record;# 原來表中的數據去重之后copy進入新表
insert into t_record_new select distinct * from t_record; -- 核心步驟#新表與原來表重命名
rename table t_record to t_record_old, t_record_new to t_record;
注意點:
-
對于重命名表和數據表的遷移一般是由數據庫管理員(DBA)來操作
-
原始表中的數據一般都不會主動刪除,但是真正查詢時不需要重復的數據,如果每次查詢都使用distinct進行去重操作,會嚴重影響效率。可以創建一張與t_record表結構相同的表,把去重的記錄寫入新表中,以后查詢都從新表中查,這樣真實數據不會丟失,同時也能保證查詢效率
11.聚合函數
常見聚合函數:
-- count統計exam表中某一列數據的量
select count(*) from exam;
select count(math) from exam;-- 語文成績小于50 的學生人數
select count(chinese) from exam where chinese < 50;-- sum統計某一列數據的總和
select sum(math) from exam;# 無法統計非數值列的和
select sum(name) from exam;-- avg統計某一列的平均數
select avg(math) from exam;# 統計總分平均分
select round(avg(chinese + math + english),2) as 總分 from exam ;-- 類比max、min用法與上述例子類似,此處不再一一贅述
12.group by
分組查詢
使用示例:
-- 準備測試表
drop table if exists emp;
create table emp(id bigint primary key auto_increment,name varchar(20) not null,role varchar(20) not null,salary decimal(10,2) not null
);# 插入測試用例
insert into emp values (1, '馬云', '老板', 1500000.00);
insert into emp values (2, '馬化騰', '老板', 1800000.00);
insert into emp values (3, '鑫哥', '講師', 10000.00);
insert into emp values (4, '博哥', '講師', 12000.00);
insert into emp values (5, '平姐', '學管', 9000.00);
insert into emp values (6, '瑩姐', '學管', 8000.00);
insert into emp values (7, '孫悟空', '游戲角色', 956.8);
insert into emp values (8, '豬悟能', '游戲角色', 700.5);
insert into emp values (9, '沙和尚', '游戲角色', 333.3);-- 統計每個角色的人數
select role, count(*) as sum from emp group by role;-- 統計每一個角色的最高、最低工資、平均工資
select role, avg(salary), min(salary), max(salary) from emp group by role;-- 顯示平均工資低于1500的角色和它的平均工資 -- having 語句支持別名
select role, avg(salary) as avg from emp group by role having avg < 1500;
-- having 與 group by的順序不可以顛倒
注意點:
-
使用
group by
進行分組處理之后,對分組的結果進行過濾的時候,不能使用where
子句,而要使用having
子句 -
Having 用于對分組結果的條件過濾
-
where用于對表中真實數據的條件過濾
-
在group by執行之前,where已經執行過了