六天帶你玩轉mysql資料庫-- 第三天筆記(下)
阿新 • • 發佈:2018-11-07
資料的高階操作:
資料操作:增刪改查
新增資料:
基本語法:
insert into 表名 [(欄位列表)] values(值列表);
在資料插入的時候,假設主鍵對應的值已經存在,插入一定會失敗。
主鍵衝突:
當主鍵存在衝突的時候(Duplicate key),可以選擇性的進行處理,更新和替換。 主鍵衝突:更新操作 insert into 表名 [(欄位列表:包含主鍵)] values(值列表) on duplicate key update 欄位 = 新值; -- 插入資料 insert into my_class values('php0810','B203'); select * from my_class; -- 發現插入錯誤重新插入 insert into my_class values('php0810','B205'); -- 衝突處理 insert into my_class values('php0810','B205') on duplicate key update room = 'B205'; select * from my_class;
主鍵衝突:替換
replace into 表名 [(欄位列表:包含主鍵)] values(值列表);
蠕蟲複製:
蠕蟲複製:從已有的資料中獲取資料,然後將資料又進行新增操作:資料成倍的增加。
表建立高階操作:從已有表建立新表(複製表結構)
create table 表名 like 資料庫.表名;
蠕蟲複製:先查出資料,然後將查出的資料新增一遍。 insert into 表名[(欄位列表)] select 欄位列表/* from 資料表名; -- 先檢視資料 select * from my_collate_bin; select * from my_gbkcopy; -- 蠕蟲複製 insert into my_gbkcopy select * from my_collate_bin; -- 檢視是否複製成功 select * from my_gbkcopy; -- 成倍增加 insert into my_gbkcopy select * from my_gbkcopy; select * from my_gbkcopy;
總結:蠕蟲複製的意義
1.從已有表拷貝資料到新表中。
2.可以迅速的讓表中的資料膨脹到一定的數量級,測試表的壓力和效率。
更新資料:
基本語法: update 表名 set 欄位 = 值 [where 條件]; 高階新增語法: update 表名 set 欄位 = 值[where 條件][limit 更新數量]; -- 更新部分a變成c update my_gbkcopy set name = 'c' where name = 'a' limit 3; -- 檢視 select * from my_gbkcopy; -- 這時候可以看到前三個a和A被換成了c,因為我們從my_collate_bin -- 中只是複製了資料而已,並不區分大小寫 -- 檢視建立表語句 show create table my_gbkcopy;
刪除資料:
刪除資料與更新類似,可以通過limit限制數量。
delete from 表名 [where 條件][limit 數量];
-- 刪除資料:限制記錄數為10
delete from my_gbkcopy where name = 'b' limit 10;
select * from my_gbkcopy;
刪除:如果表中存在主鍵自增長,那麼當刪除之後,自增長不會還原。
思考:資料的刪除是不會改變表結構,只能刪除表後重建表
Truncate 表名; -- 先刪除改變,再新增改變
-- 清空表:重置自增長
truncate my_student;
查詢資料:
基本語法:
select 欄位列表/* from 表名 [where 條件];
完整語法:
select [select 選項] 欄位列表[欄位別名]/* from 資料來源 [where 條件子句][group by 子句][having 子句]
[order by 子句][limit 子句];
select 選項:select對查出來的結果的處理方式
All:預設的,保留所有結果
Distinct:去重,查出來的結果,將重複的去除(所有欄位都相同)
-- select選項
select * from my_gbkcopy;
select all * from my_gbkcopy;
-- 去重
select distinct * from my_gbkcopy;
欄位別名:
欄位別名:當資料進行查詢出來的時候,有時候名字並不一定就滿足要求(多表查詢的時候,會有同名欄位),需要對
欄位名進行重新命名:別名。
語法:欄位名 [as] 別名;
-- 插入資料
insert into my_student values(null,'itcast0001','zs','男'),
(null,'itcast0001','zsa','男'),
(null,'itcast0004','zss','女'),
(null,'itcast0003','zsd','男'),
(null,'itcast0002','zsw','男');
-- 欄位別名
select id,
number as 學號,
name as 姓名,
sex 性別 from my_student;
資料來源:資料的來源,關係型資料庫的來源都是資料表,本質上只要保證資料類似二維表,最終都可以作為資料來源。
資料來源分為多種:單表資料來源,多表資料來源,查詢語句
單表資料來源:select * from 表名;
多表資料來源:
select * from 表名1,表名2;
-- 多表資料來源
select * from my_student,my_class;
從一張表中取出一條記錄去另外一張表中匹配所有記錄,而且全部保留(記錄數和欄位數)將這種結果稱之為笛卡爾積。
笛卡爾積稱為交叉連線,沒有什麼用,所以應該儘量避免。
子查詢:資料的來源是一條查詢語句(查詢語句的結果是二維表)
select * from(select 語句 as 表名);
-- 子查詢
select * from (select * from my_student); 查詢會報錯
select * from (select * from my_student) as s;
where 子句
where 子句:用來判斷篩選資料;where子句返回兩種結果:0或者1,0代表false,1代表true。
判斷表示式:比較運算子:>,<,>=,<=,!=,<>表示不等於,=,like,between,and,in/not in
邏輯運算子:&&(and),||(or),!(not)
where原理:where是唯一一個直接從磁盤獲取資料的時候就開始判斷的條件:從磁碟取出一條記錄開始進行where判斷,判斷
的結果如果成立儲存到記憶體,如果失敗就放棄。
-- 增加一個age和height欄位
alter table my_student add age tinyint unsigned;
alter table my_student add height tinyint unsigned;
select * from my_student;
-- 增加值:rand取得一個0到1的隨機數,floor向下取整
update my_student set age = (rand() * 20 + 20),height = floor(rand() * 20 + 170);
select * from my_student;
條件查詢1:要求找出學生ID為1,3,5的學生
-- 條件查詢1:要求找出學生ID為1,3,5的學生
select * from my_student where id = 1 || id = 3 || id = 5; -- 邏輯判斷
select * from my_student where id in (1,3,5); -- 落在集合中
條件查詢2:查出區間落在180-190之間的學生:
-- 找出身高在180-190之間的學生
select * from my_student where height > 180 and height < 190;
select * from my_student where height between 180 and 190;
這裡需要注意between和and之間的數值左邊的一定要比右邊的小。
select * from my_student where 1; -- 所有結果都滿足
group by 子句:
group by:分組的意思,根據某個欄位進行分組(相同的放一組,不同的放到不同的組)
基本語法:group by 欄位名;
分組的意義在於為了統計資料(按組統計,按分組欄位進行資料統計)
SQL提供了一系列統計函式
count():統計分組後的記錄數:每一組有多少個記錄
max():統計每組中的最大值
min():統計每組中的最小值
avg():統計每組的平均值
sum():統計每組的和
-- 分組統計:身高高矮,年齡平均,和
select sex,count(*),max(height),min(height),avg(age),sum(age) from my_student group by sex;
count()函式:裡面可以使用兩種引數:*代表統計記錄,欄位名代表統計對應的欄位(null不統計)
-- 分組統計:身高高矮,年齡平均,和
select sex,count(*),max(height),min(height),avg(age),sum(age) from my_student group by sex;
select sex,count(*),count(age),max(height),min(height),avg(age),sum(age) from my_student group by sex;
很明顯可以看出來統計的時候男的在前,是什麼問題呢?
原因在於分組會自動排序,根據分組欄位預設升序。
男的拼音nan在女的拼音nv前面導致統計男的在前。
測試:
設定升降序:
group by 欄位 [asc|desc]; -- 對分組的結果進行合併然後排序
多欄位分組:先根據一個欄位進行分組,然後再根據分組的結果再次根據某個欄位進行分組。
準備一個數據表進行實驗:
-- 多欄位分組
select c_id,sex,count(*) from my_student group by c_id,sex; -- 多欄位排序
有一個函式可以對分組的結果中的某個欄位進行字串連線(保留該組所有的某個欄位)
group_concat(欄位);
回溯統計:with rollup
任何一個分組後的結果都有一個小組,最後都需要向上級分組進行彙報統計:根據當前分組的欄位,這就是回溯統計。
回溯統計的時候會將分組欄位置空。
-- 統計
select c_id,count(*) from my_student group by c_id;
-- 回溯統計
select c_id,count(*) from my_student group by c_id with rollup;
多欄位回溯:考慮第一層分組會有此回溯:第二次分組要看第一次分組的組數,組數是多少回溯就是多少,然後加上第一層回溯即可。
-- 多欄位分組回溯統計
select c_id,sex,count(*),group_concat(name) from my_student group by c_id,sex;
select c_id,sex,count(*),group_concat(name) from my_student group by c_id,sex with rollup;
having 子句
having 子句:與where 子句一樣進行條件判斷的,where是針對磁碟資料進行判斷,進入到記憶體之後會進行分組操作,
分組結果需要having進行操作。having可以做where能做的幾乎所有事情,但是where卻不能做having能做的很多事情。
比如:1.分組統計的結果或者說統計函式都只有having能夠操作。
-- 求出每個班所有班級人數大於等於2的學生人數
select c_id,count(*) from my_student group by c_id having count(*) >= 2;
如果使用where的話得放在分組之前,那麼分組就是無效的
2.having能夠使用欄位別名:where不能,where是從磁碟讀取資料,而名字只可能是欄位名,別名是在欄位進入記憶體之後才會產生。
select c_id,count(*) as xfl from my_student group by c_id having xfl >= 2;
order by子句:
order by:排序,根據某個欄位進行升序或者降序,依賴於校對集
使用基本語法:
order by 欄位名 [asc|desc]; -- asc是升序(預設的排序方式),desc是降序
-- 排序
select * from my_student order by c_id;
多欄位排序:先根據某個欄位進行排序,然後根據排序好的欄位再按照某個資料進行再次排序。第二欄位排序是根據
第一欄位排序的結果,不會導致第一欄位排序的結果混亂。
-- 多欄位排序
select * from my_student order by c_id,sex desc;
select * from my_student order by c_id,sex; -- 進行對比
limit 子句:
limit 子句:是一種限制結果的語句,限制數量但不侷限於限制數量。
limit有兩種使用方式:
1.只用來限制長度(資料量):limit 資料量;
-- 查詢學生:前兩個
select * from my_student limit 2;
2.限制起始位置,限制數量:limit 起始位置,長度; -- 從指定的位置開始往後找資料
這種方式主要用來實現資料的分頁:當資料量很大的時候很好處理資料,分頁的效果為使用者節省時間,
提交伺服器的響應效率,減少資源的浪費:
對於使用者來講:可以點選分頁按鈕:1,2,3,4
對於伺服器而言:根據使用者選擇的頁碼來獲取不同的資料:limit offset,length;
length:每頁顯示的數量:基本不變
offset:offset = (頁碼 - 1) * 每頁顯示量
-- 查詢學生:前兩個
select * from my_student limit 0,2; -- 記錄數從0開始編號
select * from my_student limit 2,2;
select * from my_student limit 4,2;