-
表的增刪查改簡稱CRUD:Create(新增),Retrieve(查找),Update(修改),Delete(刪除)。
-
CRUD的操作對(duì)象是對(duì)表當(dāng)中的數(shù)據(jù),是典型的DML語句(Data Manipulation Language 數(shù)據(jù)操作語言)。
一、Create
語法:
INSERT [INTO] table_name
[(column [, column] ...)]
VALUES (value_list) [, (value_list)] ...
// 解釋: value_list: value, [, value] ...
說明:
- SQL中大寫的表示關(guān)鍵字,[ ]中代表的是可選項(xiàng)。
- SQL中的每個(gè)
value_list
都表示插入的一條記錄,每個(gè)value_list
都由若干待插入的列值組成。 - SQL中的
column
列表,用于指定每個(gè)value_list
中的各個(gè)列值應(yīng)該插入到表中的哪一列。
為了方便進(jìn)行演示,下面創(chuàng)建一個(gè)學(xué)生表,表當(dāng)中包含自增長的主鍵id、學(xué)號(hào)、姓名和QQ號(hào)。如下:
create table students(
id int unsigned primary key auto_increment,
sn int unsigned not null unique comment '學(xué)號(hào)',
name varchar(20) not null comment '姓名',
qq varchar(15) unique comment 'qq號(hào)碼'
);
desc students;
單行數(shù)據(jù) + 全列插入
當(dāng)我們?cè)谑褂?code>insert語句向?qū)W生表中插入記錄,每次向表中插入一條記錄,并且插入記錄時(shí)不指定column
列表,表示按照表中默認(rèn)的列順序進(jìn)行全列插入,因此插入的每條記錄中的列值需要按表列順序依次列出。如下:
insert into students values(100, 1000, '唐玄奘', null);
insert into students values(101, 1023, '孫悟空', null);
select * from students;
多行數(shù)據(jù) + 指定列插入
使用insert
語句也可以一次向表中插入多條記錄,插入的多條記錄之間使用逗號(hào)隔開,并且插入記錄時(shí)可以只指定某些列進(jìn)行插入。如下:
insert into students(sn, name) values (123, '曹操'), (187,'劉備');
select * from students;
插入否則更新
有時(shí)候我們?cè)谙虮碇胁迦胄掠涗洉r(shí),由于 主鍵 或者 唯一鍵 對(duì)應(yīng)的值已經(jīng)存在而導(dǎo)致我們插入失敗。
這時(shí)如果我們還想插入我們的數(shù)據(jù)就可以選擇性的進(jìn)行同步更新操作:
插入否則更新的SQL語法如下:
INSERT ... ON DUPLICATE KEY UPDATE column1=value1 [, column2=value2] ...;
作用:
- 如果表中沒有沖突數(shù)據(jù),則直接插入數(shù)據(jù)。
- 如果表中有沖突數(shù)據(jù),則將表中的數(shù)據(jù)進(jìn)行更新。
說明:
- SQL中大寫的表示關(guān)鍵字,[ ]中代表的是可選項(xiàng)。
- SQL中INSERT之后語法與之前的INSERT語句相同。
- UPDATE后面的column=value,表示當(dāng)插入記錄出現(xiàn)沖突時(shí)需要更新的列值。
例如:這次我們繼續(xù)向?qū)W生表中剛才的插入記錄。如下:
insert into students (id,sn,name) values(100, 1000, '唐僧') on duplicate key update name= '唐僧', sn= 1010;
可以看到在沖突的情況下我們也確實(shí)更新了數(shù)據(jù)。
說明:執(zhí)行插入否則更新的SQL后,可以通過受影響的數(shù)據(jù)行數(shù)來判斷本次數(shù)據(jù)的插入情況:
-
0 rows affected
:表中有沖突數(shù)據(jù),但沖突數(shù)據(jù)的值和指定更新的值相同。 -
1 row affected
:表中沒有沖突數(shù)據(jù),數(shù)據(jù)直接被插入。 -
2 rows affected
:表中有沖突數(shù)據(jù),并且數(shù)據(jù)已經(jīng)被更新。
替換數(shù)據(jù)
- 如果表中沒有沖突數(shù)據(jù),則直接插入數(shù)據(jù)。
- 如果表中有沖突數(shù)據(jù),則先將表中的沖突數(shù)據(jù)刪除,然后再插入數(shù)據(jù)。
語法:
- 只需要在插入數(shù)據(jù)時(shí)將SQL語句中的
INSERT
改為REPLACE
即可
replace into students(sn, name) values(1023, '孫行者');
執(zhí)行替換數(shù)據(jù)的SQL后,也可以通過受影響的數(shù)據(jù)行數(shù)來判斷本次數(shù)據(jù)的插入情況:
-
1 row affected
:表中沒有沖突數(shù)據(jù),數(shù)據(jù)直接被插入。 -
2 rows affected
:表中有沖突數(shù)據(jù),沖突數(shù)據(jù)被刪除后重新插入。
二、Retrieve
查找其實(shí)是我們使用mysql
最多的操作,其語法如下:
SELECT [DISTINCT] {* | {column1 [, column2] ...}} FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...];
說明:
- SQL中大寫的表示關(guān)鍵字,[ ]中代表的是可選項(xiàng)。
- { }中的
|
代表可以選擇左側(cè)的語句或右側(cè)的語句。
為了方便我們進(jìn)行演示,下面創(chuàng)建一個(gè)成績表,表當(dāng)中包含:自增長的主鍵id、姓名、以及該同學(xué)的語文成績、數(shù)學(xué)成績和英語成績。如下:
CREATE TABLE exam_result (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL COMMENT '同學(xué)姓名',
chinese float DEFAULT 0.0 COMMENT '語文成績',
math float DEFAULT 0.0 COMMENT '數(shù)學(xué)成績',
english float DEFAULT 0.0 COMMENT '英語成績'
);
接下來向表中插入幾條測(cè)試記錄,以供我們進(jìn)行查找。如下:
INSERT INTO exam_result (name, chinese, math, english) VALUES
('唐三藏', 67, 98, 56),
('孫悟空', 87, 78, 77),
('豬悟能', 88, 98, 90),
('曹孟德', 82, 84, 67),
('劉玄德', 55, 85, 45),
('孫權(quán)', 70, 73, 78),
('宋公明', 75, 65, 30);
1、SELECT 列
1、全列查詢
通過全列查詢我們能夠拿到所有列的數(shù)據(jù),在查詢數(shù)據(jù)時(shí)直接用*
代替column
列表,表示進(jìn)行全列查詢。如下:
select * from exam_result;
通常情況下不建議使用*
進(jìn)行全列查詢
- 查詢的列越多,意味著需要傳輸?shù)臄?shù)據(jù)量越大(MySQL采用的CS模式);
- 可能會(huì)影響到索引的使用。
2、指定列查詢
在查詢數(shù)據(jù)時(shí)也可以只對(duì)指定的列進(jìn)行查詢,這時(shí)將需要查詢的列在column
列表列出即可。
例如我們現(xiàn)在要看一下班級(jí)中的數(shù)學(xué)成績,如下:
select name, math from exam_result;
3、結(jié)果去重
當(dāng)然,我們也可以在select
后面跟上distinct
,表示對(duì)結(jié)果去重,下面我們嘗試對(duì)上面的7個(gè)數(shù)學(xué)成績進(jìn)行去重。
select distinct name, math from exam_result;
我們發(fā)現(xiàn)好像沒有達(dá)到我們想象的效果,還是有兩個(gè)相同的數(shù)據(jù),這時(shí)為什么呢?
因?yàn)?code>distinct是對(duì)結(jié)果進(jìn)行去重,而我們結(jié)果中不僅有數(shù)學(xué)成績還有姓名,這兩個(gè)組合起來沒有重復(fù)所以也就不會(huì)被去重了。
因此我們?cè)趯?duì)數(shù)學(xué)成績進(jìn)行去重時(shí)不應(yīng)該加上姓名,使用下面的SQL進(jìn)行去重:
select distinct math from exam_result;
可以看到我們的結(jié)果變成了6行(以前是7行),而且沒有重復(fù)數(shù)據(jù)
4、查詢字段為表達(dá)式
select
語句是一個(gè)非常特殊的語句,其在查詢數(shù)據(jù)時(shí),column列表中除了能羅列表中存在的列名外,我們也可以將表達(dá)式羅列到column列表中。如下:
select name, math, 1+1 from exam_result;
因此select
不僅能夠用來查詢數(shù)據(jù),還可以用來計(jì)算某些表達(dá)式或執(zhí)行某些函數(shù)。如下:
如果我們將表達(dá)式羅列到column
列表中:
-
那么每當(dāng)一條記錄被篩選出來時(shí)就會(huì)執(zhí)行這個(gè)表達(dá)式,然后將表達(dá)式的計(jì)算結(jié)果作為這條記錄的一個(gè)列值進(jìn)行顯示。
-
column列表中的表達(dá)式可以包含表中已有的字段,這時(shí)每當(dāng)一條記錄被篩選出來時(shí),就會(huì)將記錄中對(duì)應(yīng)的列值提供給表達(dá)式進(jìn)行計(jì)算。
例如:我們將每個(gè)同學(xué)的數(shù)學(xué)成績都加10分。
select name, math, math+10 from exam_result;
又或者我們可以求一下同學(xué)的總分:
select name, math+chinese+english from exam_result;
5、為查詢結(jié)果指定別名
為查詢結(jié)果指定別名的SQL語法如下:
SELECT column [AS] alias_name [...] FROM table_name;
說明:
- SQL中大寫的表示關(guān)鍵字,[ ]中代表的是可選項(xiàng)。
比如剛才查詢成績表中的數(shù)據(jù)時(shí),求總分后的名字為math+chinese+english
,有一點(diǎn)丑陋,我們使用別名進(jìn)行解決。如下:
select name, math+chinese+english as total from exam_result;
2、WHERE 條件
通過剛才的學(xué)習(xí)我們對(duì)一列的數(shù)據(jù)能夠進(jìn)行很好的操作了,但是有些時(shí)候,某一列的數(shù)據(jù)特別多,我們想要快速的找到我們想要的行,于是就需要有where
條件了!
where
子句添加與否的區(qū)別:
- 如果在查詢數(shù)據(jù)時(shí)沒有指定
where
子句,那么會(huì)直接將表中所有的記錄作為數(shù)據(jù)源來依次執(zhí)行select
語句。 - 如果在查詢數(shù)據(jù)時(shí)指定了
where
子句,那么在查詢數(shù)據(jù)時(shí)會(huì)先根據(jù)where子句篩選出符合條件的記錄,然后將符合條件的記錄作為數(shù)據(jù)源來依次執(zhí)行select語句。(非常重要?。。?
where
子句中可以指明一個(gè)或多個(gè)篩選條件,各個(gè)篩選條件之間用邏輯運(yùn)算符AND
或OR
進(jìn)行關(guān)聯(lián),下面給出了where
子句中常用的比較運(yùn)算符和邏輯運(yùn)算符。
- 注意MySQL中的的NULL不能參與任何運(yùn)算
比較運(yùn)算符:
運(yùn)算符 | 說明 |
---|---|
>、>=、<、<= | 大于、大于等于、小于、小于等于 |
= | 等于。NULL不安全,例如NULL=NULL的結(jié)果是NULL而不是TRUE(1) |
<=> | 等于。NULL安全,例如NULL<=>NULL的結(jié)果就是TRUE(1) |
!=、<> | 不等于,NULL不安全 |
BETWEEN a0 AND a1 | 范圍匹配。如果a0<=value<=a1,則返回TRUE(1) |
IN(option1, option2, …) | 如果是IN中的任意一個(gè)option,則返回TRUE(1) |
IS NULL | 如果是NULL,則返回TRUE(1) |
IS NOT NULL | 如果不是NULL,則返回TRUE(1) |
LIKE | 模糊匹配。%表示任意多個(gè)字符(包括0個(gè)),_表示任意一個(gè)字符 |
邏輯運(yùn)算符:
運(yùn)算符 | 說明 |
---|---|
AND | 多個(gè)條件同時(shí)為TRUE(1),則結(jié)果為TRUE(1),否則為FALSE(0) |
OR | 任意一個(gè)條件為TRUE(1),則結(jié)果為TRUE(1),否則為FALSE(0) |
NOT | 條件為TRUE(1),則結(jié)果為FALSE(0);條件為FALSE(0),則結(jié)果為TRUE(1) |
下面我們來做一些案例幫助我們理解并掌握這些運(yùn)算符:
1、查詢英語不及格的同學(xué)及其英語成績
在where
子句中指明篩選條件為英語成績小于60,我們直接使用<
運(yùn)算符即可。如下:
select name, english from exam_result where english < 60;
2、查詢語文成績?cè)?0到90分的同學(xué)及其語文成績
在where
子句中指明篩選條件為語文成績,然后根據(jù)分?jǐn)?shù)直接>=80 ,<= 90
即可,然后根據(jù)其并列關(guān)系條件我們選擇and
邏輯運(yùn)算符進(jìn)行連接 。如下:
select name, chinese from exam_result where chinese >= 80 and chinese <= 90;
此外,這里也可以使用BETWEEN a0 AND a1
來指明語文成績的的所在區(qū)間。如下:
select name, chinese from exam_result where chinese between 80 and 90;
3、數(shù)學(xué)成績是 58 或者 59 或者 98 或者 99 分的同學(xué)及數(shù)學(xué)成績
在where
子句中指明篩選條件為數(shù)學(xué)成績等于58
或59
或98
或99
,在select
的column
列表中指明要查詢的列為姓名和數(shù)學(xué)成績。如下:
select name ,math from exam_result where math=58 or math=59 or math=98 or math=99;
此外,這里也可以通過IN(58, 59, 98, 99)
的方式來判斷數(shù)學(xué)成績是否符合篩選要求。如下:
select name, math from exam_reault where math in (58,59,98,99);
4、姓孫的同學(xué) 及 孫某同學(xué)
- 查詢姓孫的同學(xué)
這里給出的查詢條件是模糊條件,所以在where
子句中通過模糊匹配來判斷當(dāng)前同學(xué)是否姓孫(需要用到%
來匹配多個(gè)字符),在select
的column
列表中指明要查詢的列為姓名。如下:
select name from exam_result where name like '孫%';
- 查詢孫某同學(xué)
這里給出的查詢條件是同樣是模糊條件,在where
子句中通過模糊匹配來判斷當(dāng)前同學(xué)是否為孫某(需要用到_
來嚴(yán)格匹配單個(gè)字符),在select
的column
列表中指明要查詢的列為姓名。如下:
select name from exam_result where name like '孫_';
5、查詢語文成績好于英語成績的同學(xué)
在where
子句中指明篩選條件為:語文成績>
英語成績,在select
的column
列表中指明要查詢的列為姓名、語文成績和英語成績。如下:
select name chinese, english from exam_result where chinese > english;
6、查詢總成績?cè)?00分以下的同學(xué)
在select
的column
列表中添加表達(dá)式查詢,查詢的表達(dá)式為語文、數(shù)學(xué)和英語成績之和,為了方便觀察可以將表達(dá)式對(duì)應(yīng)的列指定別名為“總分”,在where
子句中指明篩選條件為三科成績之和小于200。如下:
select name, chinese, math, english, chinese+math+english 總分 from exam_result where 總分 < 200;
結(jié)果出現(xiàn)了錯(cuò)誤,為什么呢?
因?yàn)榍懊嫖覀冋f過where
子句的執(zhí)行順序是在select
之前的,而我們是在select
時(shí)才進(jìn)行了取別名,所以where
子句中的總分
字段找不到,因此報(bào)錯(cuò)。
而且我們的where
子句中也不支持起別名。所以我們只能完整寫出:
select name, chinese, math, english , chinese+math+english 總分 from exam_result where chinese+math+english < 200;
注意點(diǎn):在where子句中不能使用select中指定的別名:
- 查詢數(shù)據(jù)時(shí)是先根據(jù)where子句篩選出符合條件的記錄。
- 然后再將符合條件的記錄作為數(shù)據(jù)源來依次執(zhí)行select語句。
7、語文成績 > 80 并且不姓孫的同學(xué)
在where子句中指明篩選條件為語文成績大于80,并且and
連接下一個(gè)條件,再通過模糊匹配和not
否定來保證該同學(xué)不姓孫,在select
的column
列表中指明要查詢的列為姓名和語文成績。如下:
select name, chinese from exam_result where chinese > 80 and name not like '孫%';
8、孫某同學(xué),否則要求總成績 > 200 并且 語文成績 < 數(shù)學(xué)成績 并且 英語成績 > 80
很顯然該題目是一個(gè)使用or
邏輯運(yùn)算符的多選題目,要求是查詢成績,被查詢的人要么是孫某,要么總成績大于200分并且語文成績小于數(shù)學(xué)成績并且英語成績大于80分,查詢時(shí)需要用到模糊匹配、表達(dá)式查詢和邏輯運(yùn)算符。如下:
select name chinese,math,english, chinese + math + english as 總分 from exam_result
where name like '孫_' or (chinese+math+english>200 andd chinese < math and english > 80);
9、NULL的查詢
在前面我們講表的創(chuàng)建時(shí)我們已經(jīng)創(chuàng)建了一張學(xué)生表,學(xué)生表中的內(nèi)容如下:
select * from students;
這里我們將數(shù)據(jù)進(jìn)行一下更新,給孫行者添加一下qq號(hào)。
update students set qq='1111111' where name='孫行者';
然后我們?cè)龠M(jìn)行查看表格
9.1、 查詢 qq 號(hào)已知的同學(xué)姓名
qq號(hào)已知即qq號(hào)不為空,所以我們需要在where子句中指明篩選條件為QQ號(hào)不為NULL,在select的column列表中指明要查詢的列為姓名和QQ號(hào)。如下:
select name, qq from students where qq is not null;
9.2、 查詢QQ號(hào)未知的同學(xué)
qq號(hào)未知即qq號(hào)為空,所以我們需要在where子句中指明篩選條件為QQ號(hào)為NULL,在select的column列表中指明要查詢的列為姓名和QQ號(hào)。如下:
select name, qq from students where qq is null;
當(dāng)然這里也可以使用<=>
來進(jìn)行判斷,但需要注意的是,在與NULL值作比較的時(shí)候應(yīng)該使用<=>
運(yùn)算符,使用=
運(yùn)算符無法得到正確的查詢結(jié)果。如下:
select name, qq from students where qq <=> null;
select name, qq from students where qq <> null;
3、結(jié)果排序
有些時(shí)候我們對(duì)我們查找到的數(shù)據(jù)可能要進(jìn)行一下排序,于是這里我們就要學(xué)習(xí)一下MySQL怎么對(duì)結(jié)果進(jìn)行排序了。
結(jié)果排序的SQL如下:
SELECT ... FROM table_name [WHERE ...] ORDER BY column [ASC | DESC] [, ...];
解釋:
- SQL中大寫的表示關(guān)鍵字,[ ]中代表的是可選項(xiàng)。
- ASC和DESC分別代表的是排升序和排降序,默認(rèn)為ASC。
注意: 如果查詢SQL中沒有order by子句,那么返回的順序是未定義的。
下面我們來進(jìn)行一些簡單的練習(xí):
1、 同學(xué)及數(shù)學(xué)成績,按數(shù)學(xué)成績升序顯示
在select的column列表中指明要查詢的列為姓名和數(shù)學(xué)成績,在order by子句中指明按照數(shù)學(xué)成績進(jìn)行升序排序。如下:
select name, math from exam_result order by math asc;
當(dāng)然我們也還可以省略order by
最后的asc
,默認(rèn)就是升序,但是這樣的寫法還是不太建議。
2、查詢同學(xué)及其QQ號(hào),按QQ號(hào)排序顯示
- 升序
這個(gè)需求也很簡單,我們只需要對(duì)qq
進(jìn)行order by asc
就行了,但是別忘了我們的students
表中的qq
有的是null
,那么結(jié)果會(huì)是什么呢?
select name, qq from students order by qq asc;
可以看出在MySQL中默認(rèn)null是比任何數(shù)據(jù)都要小的!
- 降序
select name, qq from students order by qq desc;
結(jié)果符合我們的預(yù)期!
3、查詢同學(xué)各門成績,依次按 數(shù)學(xué)降序,英語升序,語文升序的方式顯示
由于排序中可能存在相同值,于是我們就要再進(jìn)行比較其他列來確定最后的相對(duì)排序了。
排序這里我們不需要使用or
來連接多個(gè)條件,在order by
子句中指明依次按照數(shù)學(xué)成績排降序、英語成績排升序和語文成績排升序。
在select
的column
列表中指明要查詢的列為姓名、數(shù)學(xué)成績、英語成績和語文成績,如下:
可以看到顯示結(jié)果是按照數(shù)學(xué)成績進(jìn)行降序排序的,而相同的數(shù)學(xué)成績之間則是按照英語成績進(jìn)行升序排序的。
說明:
-
order by
子句中可以指明按照多個(gè)字段進(jìn)行排序,每個(gè)字段都可以指明按照升序或降序進(jìn)行排序,各個(gè)字段之間使用逗號(hào)隔開,排序優(yōu)先級(jí)與書寫順序相同。 - 例如上述SQL中,當(dāng)兩條記錄的數(shù)學(xué)成績相同時(shí)就會(huì)按照英語成績進(jìn)行排序,如果這兩條記錄的英語成績也相同就會(huì)繼續(xù)按照語文成績進(jìn)行排序,以此類推。
4、查詢同學(xué)及總分,由高到低
在select的column列表中指明要查詢的列為姓名和總分,在order by子句中指明按照總分進(jìn)行降序排序。如下:
select name, chinese+ math + english 總分 from exam_result order by 總分 desc;
那么這里的別名為什么我們order by
中能夠使用呢?
因?yàn)橹挥杏辛藬?shù)據(jù)才能對(duì)數(shù)據(jù)進(jìn)行排序,所以order by
子句的執(zhí)行的優(yōu)先級(jí)是非常低的!所以order by
能夠使用select
中的別名。
- 查詢數(shù)據(jù)時(shí)是先根據(jù)where子句篩選出符合條件的記錄。
- 然后再將符合條件的記錄作為數(shù)據(jù)源來依次執(zhí)行select語句。
- 最后再通過order by子句對(duì)select語句的執(zhí)行結(jié)果進(jìn)行排序。
也就是說,order by子句的執(zhí)行是在select語句之后的,所以在order by子句中可以使用別名。
5、查詢姓孫的同學(xué)或姓曹的同學(xué)及其數(shù)學(xué)成績,按數(shù)學(xué)成績降序顯示
由于這里要排序的不是所有數(shù)據(jù),所以這里面我們要結(jié)合 where
子句 和 order by
子句。
這里我們先通過where
子句模糊匹配找到人:
select name, math from exam_result where name like '孫%' or name like '曹%';
當(dāng)查詢到目標(biāo)數(shù)據(jù)后再在查詢SQL后添加order by
子句,在order by
子句中指明按照數(shù)學(xué)成績進(jìn)行降序排序。如下:
select name, math from exam_result where name like '孫%' or name like '曹%' order by math desc;
4、篩選分頁結(jié)果
有時(shí)候我們即使經(jīng)過了數(shù)據(jù)的篩選,但是數(shù)據(jù)依然很多,如果我們直接查看的話是不利于我們進(jìn)行操作的,所以有時(shí)候我們還要對(duì)我們的數(shù)據(jù)進(jìn)行分頁顯示。
篩選分頁結(jié)果的語法如下:
從第0條記錄開始,向后篩選出n條記錄:
SELECT ... FROM table_name [WHERE ..] [ORDER BY ...] LIMIT n;
從第s條記錄開始,向后篩選出n條記錄:
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT s, n;
從第s條記錄開始,向后篩選出n條記錄:
SELECT ... FROM table_name [WHERE ...] [ORDER BY ...] LIMIT n OFFSET s;
說明:
- SQL中大寫的表示關(guān)鍵字,
[ ]
中代表的是可選項(xiàng)。 - 查詢SQL中各語句的執(zhí)行順序?yàn)椋?code>where、
select
、order by
、limit
。 -
limit
子句在篩選記錄時(shí),記錄的下標(biāo)從0開始。
建議: 對(duì)未知表進(jìn)行查詢時(shí)最好在查詢SQL后加上limit 1
,避免在查詢?nèi)頂?shù)據(jù)時(shí)因?yàn)楸碇袛?shù)據(jù)過大而導(dǎo)致數(shù)據(jù)庫卡死。
例、按 id 進(jìn)行分頁,每頁 3 條記錄,分別顯示 第 1、2、3 頁
我們先來看一看所有的數(shù)據(jù):
select * from exam_result;
查詢第1頁記錄時(shí)在查詢?nèi)頂?shù)據(jù)的SQL后,加上limit 3
子句表示從第0條向后篩選出3條記錄。如下:
select * from exam_result limit 3;
現(xiàn)在我們完成了第一頁的顯示,但是我們要進(jìn)行第二頁的顯示時(shí),我們就要指明起始位置為3
了,于是我們的limit
子句就要變成了limit 3,3
。
select * from exam_result limit 3,3;
最后一頁,同理我們可以使用limit 6,3
,也可以使用 limit 3 offset 6
,表明從第6條記錄開始,向后篩選出3條記錄。如下:
select * from exam_result limit 3 offset 6;
因?yàn)閺谋碇泻Y選出的記錄不足3個(gè),所以篩選出幾個(gè)就顯示幾個(gè)。
三、Update
修改數(shù)據(jù)的SQL如下:
UPDATE table_name SET column1=expr1 [, column2=expr2] ... [WHERE ...] [ORDER BY ...] [LIMIT ...];
說明:
- SQL中大寫的表示關(guān)鍵字,[ ]中代表的是可選項(xiàng)。
- SQL中的
column=expr
,表示將記錄中列名為column的值修改為expr。 - 在修改數(shù)據(jù)之前需要先找到待修改的記錄,update語句中的where、order by和limit就是用來定位數(shù)據(jù)的。
1、將孫悟空同學(xué)的數(shù)學(xué)成績修改為80分
在修改數(shù)據(jù)之前,我們先查看孫悟空同學(xué)當(dāng)前的數(shù)學(xué)成績。如下:
select name, math from exam_result where name='孫悟空';
在update
語句中指明要將篩選出來的記錄的數(shù)學(xué)成績改為80分,并在修改后再次查看數(shù)據(jù)確保數(shù)據(jù)成功被修改。如下:
update exam_result set math=80 where name='孫悟空';
2、將曹孟德同學(xué)的數(shù)學(xué)成績修改為60分,語文成績修改為70分
同理,在修改數(shù)據(jù)之前,先查看曹孟德同學(xué)當(dāng)前的數(shù)學(xué)成績和語文成績。如下:
select * from exam_result where name='曹孟德';
在update
語句中指明要將篩選出來的記錄的數(shù)學(xué)成績改為60分,語文成績改為70分,并在修改后再次查看數(shù)據(jù)確保數(shù)據(jù)成功被修改。如下:
select * from exam_result where name='曹孟德';
3、將總成績倒數(shù)前三的3位同學(xué)的數(shù)學(xué)成績加上30分
在修改數(shù)據(jù)之前,先查看總成績倒數(shù)前三的3位同學(xué)的數(shù)學(xué)成績。如下:
select name, chinese+math+english 總分 from exam_result order by 總分 asc;
select name, chinese+math+english 總分 from exam_result order by 總分 asc limit 3;
在update
語句中指明要將篩選出來的記錄的數(shù)學(xué)成績加上30分,如下:
update exam_result set math = math + 30 order by chinese+math+english asc limit 3;
并在修改后再次查看數(shù)據(jù)確保數(shù)據(jù)成功被修改。
需要注意的是,MySQL中不支持+=
這種復(fù)合賦值運(yùn)算符,此外,這里在查看更新后的數(shù)據(jù)時(shí)不能查看總成績倒數(shù)前三的3位同學(xué),因?yàn)橹翱偝煽兊箶?shù)前三的3位同學(xué),數(shù)學(xué)成績加上30分后可能就不再是倒數(shù)前三了。
4、將所有同學(xué)的語文成績修改為原來的2倍
在修改數(shù)據(jù)之前,先查看所有同學(xué)的語文成績。如下:
在update
語句中指明要將篩選出來的記錄的語文成績變?yōu)樵瓉淼?倍,因?yàn)橐薷牡牡乃型瑢W(xué)所以我們不需要使用where
子句,如下:
update exam_result set chinese = chinese * 2 ;
查看修改后的數(shù)據(jù):
注意: 這里沒有 where
子句,會(huì)更新全表,更新全表的語句要慎用!
四、Delete
刪除數(shù)據(jù)的SQL如下:
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...];
說明:
- SQL中大寫的表示關(guān)鍵字,[ ]中代表的是可選項(xiàng)。
- 在刪除數(shù)據(jù)之前需要先找到待刪除的記錄,
delete
語句中的where、order by
和limit
就是用來定位數(shù)據(jù)的。
1、刪除數(shù)據(jù)
刪除表中的某個(gè)條目
刪除孫悟空同學(xué)的考試成績
在刪除數(shù)據(jù)之前,先查看孫悟空同學(xué)的相關(guān)信息。
select * from exam_result where name='孫悟空';
然后在delete語句中指明刪除孫悟空對(duì)應(yīng)的記錄,并在刪除后再次查看數(shù)據(jù)確保數(shù)據(jù)成功被刪除。如下:
delete from exam_result where name='孫悟空';
刪除整張表數(shù)據(jù)
刪除整表的操作很簡單,我們只要不在delete
后面加where
子句,這樣我們就能夠刪除整個(gè)表了
注意:刪除整表操作要慎用!
我們先來準(zhǔn)備一張測(cè)試表,表中包含一個(gè)自增長的主鍵id和姓名。如下:
create table test( id int primary key auto_increment, name varchar(10));
desc test;
插入數(shù)據(jù),并查看數(shù)據(jù)
insert into test(name) values ('A'),('B'),('C');
select * from test;
這里我們順便看一下test
表的主鍵值的相關(guān)信息,方便我們解釋下面的截?cái)啾?/strong>問題:
現(xiàn)在我們?cè)?code>delete語句中只指明要?jiǎng)h除數(shù)據(jù)的表名,而不通過where
、order by
和limit
指明篩選條件,這時(shí)將會(huì)刪除整張表的數(shù)據(jù)。如下:
這里我們?cè)俅尾榭匆幌?code>test表的主鍵值的相關(guān)信息:
show create table test \G
我們?cè)诓迦胍恍?shù)據(jù)進(jìn)行驗(yàn)證:
insert into test(name) values ('D'), ('E'), ('F');
select * from test;
再次查看主鍵值的相關(guān)信息:
show create table test \G
注意:當(dāng)通過delete語句刪除整表數(shù)據(jù)時(shí),不會(huì)重置AUTO_INCREMENT=n字段!
如果我們想要清除AUTO_INCREMENT=n字段,可以使用截?cái)啾?/strong>!
2、截?cái)啾?/h3>
截?cái)啾淼腟QL語法如下:
TRUNCATE [TABLE] table_name;
說明:
- SQL中大寫的表示關(guān)鍵字,[ ]中代表的是可選項(xiàng)。
-
truncate
只能對(duì)整表操作,不能像delete
一樣針對(duì)部分?jǐn)?shù)據(jù)操作。 -
truncate
實(shí)際上不對(duì)數(shù)據(jù)操作,所以比delete
更快。 -
truncate
在刪除數(shù)據(jù)時(shí)不經(jīng)過真正的事務(wù),所以無法回滾。 -
truncate
會(huì)重置AUTO_INCREMENT=n
字段。
為了演示truncate
的效果,我們創(chuàng)建一張測(cè)試和原來一樣表,表中包含一個(gè)自增長的主鍵id和姓名。如下:
create table for_truncate(
id int primary key auto_increment,
name varchar(10)
);
insert into for_truncate(name) values ('A'),('B'),('C');
select * from for_truncate;
我們查看一下表for_truncate
主鍵值的相關(guān)信息:
show create table for_truncate \G
然后我們就要通過truncate
刪除這張表了,在truncate
語句中只指明要?jiǎng)h除數(shù)據(jù)的表名,這時(shí)便會(huì)刪除整張表的數(shù)據(jù),但由于truncate實(shí)際不對(duì)數(shù)據(jù)操作,因此執(zhí)行truncate語句后看到影響行數(shù)為0。如下:
再次查看表for_truncate
主鍵值的相關(guān)信息
再向表中插入一些數(shù)據(jù),在插入數(shù)據(jù)時(shí)不指明自增長字段的值,這時(shí)會(huì)發(fā)現(xiàn)插入數(shù)據(jù)對(duì)應(yīng)的自增長id值是重新從1開始增長的。如下:
insert into for_truncate(name) values ('D'), ('E'), ('F');
select * from for_truncate;
再次查看表for_truncate
主鍵值的相關(guān)信息
show create table for_truncate \G
注意: truncate
在刪除數(shù)據(jù)時(shí)不經(jīng)過真正的事務(wù),無法回滾,所以截?cái)啾聿僮饕饔茫?/p>
六、插入查詢結(jié)果
經(jīng)過上面的學(xué)習(xí),我們對(duì)于表的增刪查改基本上都沒有問題了,但是在這里我們還要學(xué)習(xí)一下如果將這些SQL組合起來使用。
例如有些時(shí)候我們要插入的數(shù)據(jù)是:某個(gè)查詢的結(jié)果,這時(shí)我們就要將SQL組合在一起了。
插入查詢結(jié)果的SQL語法:
INSERT INTO table_name [(column [, column ...])] SELECT ...
說明:
- SQL中大寫的表示關(guān)鍵字,[ ]中代表的是可選項(xiàng)。
- 此條SQL的作用是將篩選出來的記錄插入到指定的表當(dāng)中。
- SQL中的column,表示將篩選出的記錄的各個(gè)列插入到表中的哪一列。
為了更好的學(xué)習(xí)這個(gè)SQL語法,我們來看一下面的這個(gè)案例:
現(xiàn)在有一張表,表中的數(shù)據(jù)是有重復(fù)的,要求如下:
刪除表中的的重復(fù)復(fù)記錄,重復(fù)的數(shù)據(jù)只能有一份
我們先來偽造一下題目的數(shù)據(jù):
- 創(chuàng)建原數(shù)據(jù)表
CREATE TABLE duplicate_table (id int, name varchar(20));
- 插入測(cè)試數(shù)據(jù)
INSERT INTO duplicate_table VALUES
(100, 'aaa'),
(100, 'aaa'),
(200, 'bbb'),
(200, 'bbb'),
(200, 'bbb'),
(300, 'ccc');
現(xiàn)在我們查看一下表中的數(shù)據(jù):
select * from duplicate_table;
那我們?cè)趺赐瓿深}目的要求呢?
思路:
-
創(chuàng)建一張空表
no_duplicate_table
,其結(jié)構(gòu)和duplicate_table
一樣的。 -
對(duì)
duplicate_table
表進(jìn)行查詢?nèi)ブ亍?/p> -
將去重的結(jié)果插入到新表
no_duplicate_table
這里我們就會(huì)發(fā)現(xiàn):第二步和第三步的SQL必須要合在一起才能完成我們想要的插入
-
將表
duplicate_table
進(jìn)行重命名為old_duplicate_table
-
將表
no_duplicate_table
進(jìn)行重命名為duplicate_table
。
操作5和操作6的重命名是為了保證底層數(shù)據(jù)表的改變不影響上層應(yīng)用的使用
- 由于創(chuàng)建的空表
no_duplicate_table
的表的結(jié)構(gòu)與duplicate_table
相同,因此在創(chuàng)建臨時(shí)表的時(shí)候可以借助like
進(jìn)行創(chuàng)建。如下:
create table no_duplicate_table like duplictae_table;
desc no_duplicate_table;
- 對(duì)
duplicate_table
表進(jìn)行查詢?nèi)ブ亍?/li>
select distinct * from duplicate_table;
- 由于表
no_duplicate_table
和表duplicate_table
的結(jié)構(gòu)相同,所以可以通過插入查詢語句將去重查詢后的結(jié)果插入到臨時(shí)表中。并且我們可以對(duì)select
進(jìn)行全列查詢,因此在插入時(shí)不用在表名后指明column
列表。如下:
insert into no_duplicate_table select distinct * from duplicate_table;
select * from no_duplicate_table;
4. 將表duplicate_table
重命名為old_duplicate_table
要修改表名,我們使用 RENAME TABLE
語句如下:
RENAME TABLE old_table_name TO new_table_name;
舊表( old_table_name)必須存在,而新表( new_table_name)一定不存在,如果新表 new_table_name 確實(shí)存在,該語句將失敗。
rename table duplicate_table to old_duplicate_table;
show tables;
- 將表
no_duplicate_table
進(jìn)行重命名為duplicate_table
。
rename table no_duplicate_table to duplicate_table;
show tables;
文章來源:http://www.zghlxwxcb.cn/news/detail-785499.html
- 最后我們?cè)谶M(jìn)行一下檢查
duplicate_table
表是否已經(jīng)經(jīng)過了去重。
文章來源地址http://www.zghlxwxcb.cn/news/detail-785499.html
到了這里,關(guān)于【MySQL】表的增刪改查的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!