前言
雖然在大一下學(xué)期,就已經(jīng)接觸到了MySQL,但是那個(gè)時(shí)候只是會(huì)用MySQL進(jìn)行增刪改查,在大三上學(xué)期,嘗試投簡(jiǎn)歷尋找實(shí)習(xí)時(shí),對(duì)方公司對(duì)于程序員的MySQL水平有很高的要求,所以我開(kāi)始系統(tǒng)化的學(xué)習(xí)MySQL。順便將整理出的筆記逐步寫(xiě)入博客中,日積月累,準(zhǔn)備發(fā)表一篇長(zhǎng)篇博客。
本篇博客的特點(diǎn)
本篇博客,我會(huì)以一個(gè)學(xué)過(guò)的人的身份給大家來(lái)講,所以里面很多部分我會(huì)以教師與學(xué)生的視角來(lái)書(shū)寫(xiě)。這可能也會(huì)讓大家比較可以接受。
MySQL的重要性
MySQL的重要性-SQL寫(xiě)的好,工作隨便找。
可以看出其實(shí)在現(xiàn)在的工作中,很多的軟件app都選擇了MySQL作為數(shù)據(jù)存儲(chǔ)的工具。但是光學(xué)語(yǔ)法有用么?固然學(xué)會(huì)了語(yǔ)法非常重要,但是實(shí)際上,MySQL在使用時(shí)的提速也非常的重要。大量的數(shù)據(jù)在處理的時(shí)候,都需要用一些算法對(duì)搜索等過(guò)程進(jìn)行優(yōu)化。
舉個(gè)栗子,假設(shè)有100萬(wàn)條數(shù)據(jù),現(xiàn)在讓你進(jìn)行查詢操作,如果不用任何的技巧,我們的思路就是直接一個(gè)循環(huán),對(duì)內(nèi)部數(shù)據(jù)進(jìn)行遍歷,這樣的速度可想而知。那么如果使用算法進(jìn)行優(yōu)化,那么速度就會(huì)有所提升。這也是很多大廠目前數(shù)據(jù)庫(kù)操作中最為常見(jiàn)的現(xiàn)象。數(shù)據(jù)量大,需求響應(yīng)時(shí)間短。
數(shù)據(jù)模型
下圖是MySQL的數(shù)據(jù)模型,我們就是客戶端,通過(guò)DBMS創(chuàng)建數(shù)據(jù)庫(kù),再?gòu)臄?shù)據(jù)庫(kù)中創(chuàng)建數(shù)據(jù)表。當(dāng)然一個(gè)數(shù)據(jù)庫(kù)可以創(chuàng)建多個(gè)數(shù)據(jù)表。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-cW6qwk4X-1667577677143)(https://note.youdao.com/yws/res/1/WEBRESOURCE0301c28c7ad0bceb41f8ffc984f66111)]
SQL通用語(yǔ)句
- 首先SQL語(yǔ)句可以單行書(shū)寫(xiě),同時(shí)也支持多行書(shū)寫(xiě),以分號(hào)作為結(jié)尾。
- SQL語(yǔ)句可以使用空格/鎖進(jìn)來(lái)增強(qiáng)語(yǔ)句的可讀性。
- MySQL數(shù)據(jù)庫(kù)的SQL語(yǔ)句不區(qū)分大小寫(xiě),但是關(guān)鍵字一般建議大寫(xiě)。
- 注釋:
- 單行注釋: # 注釋內(nèi)容 或者 – 注釋內(nèi)容
- 多行注釋: /* 注釋內(nèi)容 */
SQL分類
分類 | 全稱 | 說(shuō)明 |
---|---|---|
DLL | Data Definition Language | 數(shù)據(jù)定義語(yǔ)言,用來(lái)定義數(shù)據(jù)庫(kù)對(duì)象(數(shù)據(jù)庫(kù),表,字段) |
DML | Data Manipulation Language | 數(shù)據(jù)操作語(yǔ)言,用來(lái)對(duì)數(shù)據(jù)庫(kù)表中的數(shù)據(jù)進(jìn)行增刪改 |
DQL | Data Query Language | 數(shù)據(jù)查詢語(yǔ)言,用來(lái)查詢數(shù)據(jù)庫(kù)中的記錄 |
DCL | Data Control Language | 數(shù)據(jù)控制語(yǔ)言,用來(lái)創(chuàng)建數(shù)據(jù)庫(kù)用戶,控制數(shù)據(jù)庫(kù)訪問(wèn)權(quán)限 |
數(shù)據(jù)庫(kù)操作
查詢
查詢所有數(shù)據(jù)庫(kù)
我們?cè)诜?wù)器或者本地搭建數(shù)據(jù)庫(kù)服務(wù)之后,我們可以創(chuàng)建很多的數(shù)據(jù)庫(kù),但是數(shù)據(jù)庫(kù)有很多了之后我們需要實(shí)時(shí)的知道都有哪些,因?yàn)樗麄兊臄?shù)據(jù)庫(kù)名稱不同,所以我們要使用下面的語(yǔ)句。
SHOW DATABASES;
可以看到在寫(xiě)好這個(gè)語(yǔ)句之后,我們所有的數(shù)據(jù)庫(kù)都會(huì)顯示出來(lái)。
查詢當(dāng)前數(shù)據(jù)庫(kù)
SELECT DATABASE();
創(chuàng)建
CREATE DATABASE [IF NOT EXISTS] 數(shù)據(jù)庫(kù)名 [DEFAULT CHARSET 字符集] [COLIATE 排序規(guī)則]
我們通過(guò)上面這句話可以創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù)。當(dāng)然IF NOT EXISTS可以幫我們判斷是否存在這個(gè)數(shù)據(jù)庫(kù)。當(dāng)存在此數(shù)據(jù)庫(kù)時(shí),將不會(huì)產(chǎn)生任何操作,在不存在此數(shù)據(jù)庫(kù)時(shí),才會(huì)創(chuàng)建一個(gè)全新的。同時(shí)我們MySQL的編碼格式不建議使用utf8的格式,我建議使用utf8mb4.
刪除
DROP DATABASE [IF EXISTS] 數(shù)據(jù)庫(kù)名;
通過(guò)上面的語(yǔ)句也可以達(dá)成刪除的效果。
刪除并重新創(chuàng)建表
TRUNCATE TABLE 表名;
使用
USE 數(shù)據(jù)庫(kù)名
數(shù)據(jù)表操作——查詢
查詢當(dāng)前數(shù)據(jù)庫(kù)中所有的表
SHOW TABLES
上面的代碼操作時(shí)對(duì)數(shù)據(jù)庫(kù)中表數(shù)據(jù)的遍歷顯示,在運(yùn)行后,可以顯示出當(dāng)前數(shù)據(jù)庫(kù)內(nèi),所有的數(shù)據(jù)表。
查詢表結(jié)構(gòu)
DESC 表名
在對(duì)表數(shù)據(jù)的結(jié)構(gòu)進(jìn)行查詢之后,可以看到表中存在一個(gè)name的列名,同時(shí)數(shù)據(jù)類型是varchar類型。可以為NULL等等信息。
查詢指定表的建表語(yǔ)句
SHOW CREATE TABLE 表名
然后我們可以通過(guò)上面的語(yǔ)法,了解如何創(chuàng)建一個(gè)表,使新的表的結(jié)構(gòu),字符完全一致。
數(shù)據(jù)表操作——?jiǎng)?chuàng)建
創(chuàng)建表
CREATE TABLE 表名 (
字段1 類型 COMMENT '注釋',
字段2 類型 COMMENT '注釋',
字段3 類型 COMMENT '注釋',
字段4 類型 COMMENT '注釋'
)
我們通過(guò)上面的語(yǔ)法變化我們想要的數(shù)據(jù)結(jié)構(gòu)來(lái)進(jìn)行創(chuàng)建,可以看到在執(zhí)行之后,一個(gè)符合我們預(yù)期效果的表數(shù)據(jù)就出現(xiàn)了。
數(shù)據(jù)表操作——數(shù)據(jù)類型
MySQL中主要支持三大類型,數(shù)值類型,字符串類型,時(shí)間日期類型。
數(shù)值類型
- TINYINT 就是1個(gè)字節(jié)的整型數(shù)據(jù)。
- SMALLINT 就是2個(gè)字節(jié)的整型。
- MEDIUMINT 就是3個(gè)字節(jié)。
- INT 正常大小的整型,占用4個(gè)字節(jié)。
- BIGINT 就是很大的整型,占用8個(gè)字節(jié)。
- FLOAT 單精度浮點(diǎn)數(shù)值
- DOUBLE 雙精度浮點(diǎn)數(shù)值
- DECIMAL 小數(shù)值
舉個(gè)例子,我們?cè)诖鎯?chǔ)某個(gè)人年齡時(shí),因?yàn)槿朔值哪挲g不會(huì)超過(guò)255,所以可以使用TINYINT類型,同時(shí)又因?yàn)槿说哪挲g不存在負(fù)數(shù),所以使用unsigned,也就是無(wú)符號(hào)類型。
字符串類型
這里我們需要區(qū)分的就是text和blob,首先text就是存儲(chǔ)文本,這個(gè)大家應(yīng)該并不陌生,但是blob是用來(lái)存儲(chǔ)二進(jìn)制文件的,很多時(shí)候,人們將圖像傳輸?shù)綌?shù)據(jù)庫(kù),就是使用的blob,同樣一些軟件安裝包也是這種效果,因?yàn)檫@樣效率不高,也不好管理。
然后我們區(qū)分一下char和varchar。首先char使是定長(zhǎng),也就是說(shuō),假設(shè)我想存儲(chǔ)一個(gè)1,那么用char的化,占用10字節(jié),其余九個(gè)位置用空格來(lái)占用。如果是varchar那就只占用1個(gè)字節(jié)。
日期時(shí)間類型
這里沒(méi)有太多要解釋的,我們一般不使用最后一種類型。
數(shù)據(jù)表操作——修改
添加字段
ALTER TABLE 表名 ADD 字段名 類型(長(zhǎng)度) [COMMENT 注釋] [約束];
可以看到我們向demo2中添加一個(gè)nickname的列信息,執(zhí)行后就出現(xiàn)了nickname。
修改數(shù)據(jù)類型
ALTER TABLE 表名 MODIFY 字段名 新數(shù)據(jù)類型(長(zhǎng)度);
在輸入上述語(yǔ)句后,我們成功將nickname字段的數(shù)據(jù)類型修改為char類型。長(zhǎng)度是10個(gè)字符。
修改字段名和字段類型
ALTER TABLE 表名 CHANGE 舊字段名 新字段名 新數(shù)據(jù)類型(長(zhǎng)度) [COMMENT 注釋] [約束];
在經(jīng)過(guò)上面的操作之后,我們的nickname成功的更改為new_nickname,并且轉(zhuǎn)換為了50字符長(zhǎng)度的varchar類型
刪除字段
ALTER TABLE 表名 DROP 字段;
在上面的語(yǔ)句執(zhí)行后,我們就可以刪除掉new_nickname字段。
修改表名
ALTER TABLE 表名 RENAME TO 新表名;
這樣我們就可以表demo2轉(zhuǎn)化為demo3
數(shù)據(jù)表操作——插入
給指定字段添加數(shù)據(jù)
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);
那么我們可以先來(lái)看一下這個(gè)語(yǔ)句,首先字段1,字段2就是想要操作的位置,那么和C語(yǔ)言中的格式化很像,我們要將值1和值2對(duì)號(hào)入座,放入對(duì)應(yīng)的字段中,實(shí)現(xiàn)插入的效果。那么我們來(lái)看一下實(shí)際操作。
這里我們要注意數(shù)據(jù)類型中,字符類型就要用單引號(hào),那么數(shù)值類型的話,就不可以使用單引號(hào)。
給全部字段添加數(shù)據(jù)
當(dāng)我們明確要給所有字段添加數(shù)值時(shí),其實(shí)就是添加一整條新的數(shù)據(jù),那么我們可以簡(jiǎn)化我們之前的SQL語(yǔ)句。因?yàn)槲覀儾恍枰タ紤]那些要添加,哪些不添加了,所以我們只需要按照數(shù)據(jù)庫(kù)中字段順序進(jìn)行書(shū)寫(xiě)就可以了。
INSERT INTO 表名 VALUES (值1, 值2, ...);
現(xiàn)在我們可以看到這樣語(yǔ)句更加簡(jiǎn)單,也很容易理解。
批量添加數(shù)據(jù)
INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...),(值1, 值2, ...);
INSERT INTO 表名 VALUES (值1, 值2, ...),(值1, 值2, ...);
上面就是批量添加數(shù)據(jù)的操作,我們可以理解為,批量添加數(shù)據(jù)就是,在添加一條數(shù)據(jù)的后面再加上一組或更多組。這個(gè)語(yǔ)句就不在展示范例了。
注意
- 插入數(shù)據(jù)時(shí),指定的字段順序需要與值的順序是一一對(duì)應(yīng)的。
- 字符串和日期類型要用單引號(hào)括起來(lái)。
- 插入的數(shù)據(jù)大小,應(yīng)該在字段的范圍內(nèi)。
數(shù)據(jù)表操作——修改
修改數(shù)據(jù)
UPDATE 表名 SET 字段名1=值1, 字段名2=值2,.....[WHERE 條件];
我們可以發(fā)現(xiàn)更新數(shù)據(jù)時(shí),set后面不需要括號(hào),只需要用逗號(hào)隔開(kāi)就好。當(dāng)然后面的WHERE條件也不是必要的,當(dāng)我們不加入條件時(shí),我們的更改就會(huì)覆蓋整個(gè)表。下面我們來(lái)看一下樣例。
可以看到我們的loading名字被修改成了wow。這個(gè)就是我們的更改方法。
刪除數(shù)據(jù)
DELETE FROM 表名 [WHERE 條件]
這個(gè)就是我們刪除數(shù)據(jù)的一個(gè)語(yǔ)句,我們只需要將數(shù)據(jù)進(jìn)行一個(gè)限定就可以做到精確刪除摸一個(gè)值的位置,那么那一整行就被我們刪除掉了。下面我們來(lái)看一下樣例。
不難看出create的數(shù)據(jù)被我們刪除了。
數(shù)據(jù)表操作——查詢
首先我們要知道,在我們平時(shí)生活中,數(shù)據(jù)庫(kù)中業(yè)務(wù)量最高的操作就是查詢操作,也就是我們的SELECT操作。當(dāng)然再M(fèi)ySQL中查詢也有很多的方式,我們這一次都要學(xué)習(xí),但是我就不像之前一樣給大家寫(xiě)一個(gè)大的總結(jié)了,我們直接來(lái)分塊學(xué)習(xí)。
基本查詢
查詢單個(gè)字段或多個(gè)字段
其實(shí)基本查詢就是我以前最為常用的,簡(jiǎn)單粗暴的方式啊,直接查詢整個(gè)數(shù)據(jù)表。我們有兩種寫(xiě)法,第一種就是分字段,只搜索我想要的字段,還有一種就是全部搜索,不管是什么字段,我全都進(jìn)行搜索。
SELECT 字段1, 字段2, ... FROM 表名;
SELECT * FROM 表名;
這就是我說(shuō)的兩種寫(xiě)法的規(guī)范方式,第一個(gè)我們輸入我們想要查詢的字段,然后說(shuō)明要在那個(gè)數(shù)據(jù)表中進(jìn)行操作,就可以得到結(jié)果。第二個(gè)就是我要表明我要查詢的表名,然后就可以獲取表中所有字段的所有數(shù)據(jù)。下面我們來(lái)看一個(gè)示例。
我們可以看到再搜索了一個(gè)姓名的字段之后,我們的數(shù)據(jù)庫(kù)給我們返回了一個(gè)字段下的所有的數(shù)值。
上面就是完全查詢的寫(xiě)法。可以發(fā)現(xiàn)它可以自動(dòng)返回所有字段的所有數(shù)據(jù)。
設(shè)置別名
SELECT 字段1 [AS 別名1], 字段2 [AS 別名2], .... FROM 表名;
那么這個(gè)別名到底有什么意義呢?在平時(shí)的使用時(shí)又有什么用處。我們來(lái)做一個(gè)對(duì)比。首先,平時(shí)我們搜索一列數(shù)據(jù),返回的結(jié)果如下圖。
看起來(lái)非常的正常對(duì)吧,但是我們想想,當(dāng)一次搜索好多列,這些字段你還看的明白是什么意思么,可能也看的明白對(duì)吧,但是如果我們把它變成中文之類的方便理解的名字是不是更好?如下圖
這個(gè)時(shí)候我們返回的結(jié)果就是姓名。是不是一眼就看懂了。
去除重復(fù)記錄
SELECT DISTINCT 字段列表 FROM 表名;
那么去除重復(fù)記錄有什么用處呢?我們舉一個(gè)例子,我們現(xiàn)在公司要統(tǒng)計(jì),員工們戶籍所在地在哪里,那么是不是會(huì)有重復(fù)的現(xiàn)象,但是我現(xiàn)在只需要知道,有的員工再北京,有的員工再上海就可以,不需要知道是誰(shuí)。所以重復(fù)的記錄就沒(méi)有意義了,那么我就可以再數(shù)據(jù)庫(kù)中進(jìn)行去重操作。
可以看到上面圖片中,我們?cè)谶M(jìn)行年齡的搜索,但是年齡的重疊太大了,所以我要進(jìn)行去重,那么使用了DISTINCT之后,得到的數(shù)據(jù)就是去重后的數(shù)據(jù)了。
條件查詢
SELECT 字段1, 字段2, ... FROM 表名 WHERE 條件列表;
上面這個(gè)就是我們的條件查詢,也是非常常用的一種查詢方式,其實(shí)在很多的項(xiàng)目中,我們都會(huì)有查詢的條件的。例如,我今天要篩選男生的人員信息,那么我現(xiàn)在就會(huì)對(duì)性別進(jìn)行條件篩選。
其實(shí)在條件列表中,有很多的查詢限制方式。如下圖
那么這些運(yùn)算符都是什么意思呢?我們來(lái)看一下。
首先大于號(hào),大于等于號(hào),小于號(hào),小于等于號(hào),等于,不等于這幾個(gè)都是非常常見(jiàn)的運(yùn)算符,我們不過(guò)多去解釋。
-
BETWEEN ... AND ...
這個(gè)是篩選范圍的運(yùn)算符,可以理解為介于哪兩個(gè)值之間,注意左側(cè)為最小值,右側(cè)為最大值。 -
IN(...)
其實(shí)這個(gè)運(yùn)算符,經(jīng)常使用Python的程序員應(yīng)該都知道,簡(jiǎn)直不要太好用,直接就可以知道一個(gè)東西是否在一個(gè)序列中。
-LIKE
占位符,我們可以理解為C語(yǔ)言中的%d %c這樣的東西,但是還存在一些區(qū)別,因?yàn)樗梢杂?,同時(shí)也可以使用_(下劃線).下劃線只能匹配一個(gè)字符,百分號(hào)可以匹配很多個(gè),例如我現(xiàn)在有一個(gè)詞典,里面有一個(gè)單詞叫abandom,那么當(dāng)你用下劃線匹配時(shí),_bandom
就可以搜索到,但是要是使用百分號(hào)的話,可以這樣%bandom
或%andom
或a%om
或ab%dom
等等都可以搜索到。 -
IS NULL
這個(gè)可以用來(lái)判斷一個(gè)字段對(duì)應(yīng)的值是不是NULL
。很好理解的。 -
AND
或者&&
這個(gè)就是C語(yǔ)言和Python都涵蓋了的,&&我相信大家不陌生吧,AND和&&意思是一樣的,它可以連接兩個(gè)條件,當(dāng)兩個(gè)條件都滿足時(shí),就可以滿足判斷查詢條件了 -
OR
或者||
這個(gè)就是或者的意思,也就是說(shuō)兩個(gè)條件中有一個(gè)滿足即可 -
NOT
或!
這個(gè)就是非,不是的意思。那么當(dāng)我們的判斷條件不滿足時(shí)那就觸發(fā)了這個(gè)非的意思。
下面我們來(lái)實(shí)際操作一下,我們先嘗試使用比較運(yùn)算符,首當(dāng)其沖的肯定是我們的大于,等于,小于,不等于這些對(duì)吧。那么我們來(lái)看一下下圖的語(yǔ)句。
我們寫(xiě)了一個(gè)搜索語(yǔ)句,里面搜索的目標(biāo)是年齡等于12的人,那么得到的結(jié)果就是兩個(gè)人的完整的數(shù)據(jù)信息。這句話中,唯一的條件語(yǔ)句就是年齡等于12。那么其他的我們就先跳過(guò)了,沒(méi)必要一個(gè)一個(gè)的展示。
下面我們來(lái)看一下IS NULL的情況,首先IS NULL不用多說(shuō),就是一個(gè)簡(jiǎn)單的是否為NULL的判斷語(yǔ)句。那么我們直接進(jìn)行搜索就可以了,結(jié)果如下圖。
然后我們來(lái)看一下Between and的語(yǔ)法結(jié)構(gòu)。這個(gè)語(yǔ)法其實(shí)就是一個(gè)范圍,我們也可以用and來(lái)進(jìn)行替代,但是既然可以用官方的,為啥要自己寫(xiě),雖然不多,但是麻煩(就是懶得寫(xiě)).
最后也是最終的就是這個(gè)LIKE,因?yàn)槠渌亩际呛芎美斫獾?,LIKE有的同學(xué)看過(guò)了解釋之后,并沒(méi)有看明白。那我們?cè)賳为?dú)的去看一下這個(gè)東西。
上面這個(gè)語(yǔ)句我們使用的時(shí)%通配符,這個(gè)就是一個(gè)可以匹配一串字符的匹配符號(hào)。所以只要首字母是w的,不管后面有多少字符,都可以被搜索出來(lái)。
但是這個(gè)就不像%這樣了,因?yàn)樗荒芷ヅ湟粋€(gè)字符,也就是說(shuō),首字母為w,并且后面只跟著一個(gè)字符的才會(huì)被搜索出來(lái)。
聚合函數(shù)
聚合函數(shù)在MySQL中,可以將一列字段當(dāng)作一個(gè)整體,進(jìn)行計(jì)算處理。具備的操作函數(shù)如下圖。
上面的圖片中的這些函數(shù)操作,可以直接作用于我們的字段進(jìn)行操作。那么怎么去書(shū)寫(xiě)呢?
SELECT 聚合函數(shù)(字段) FROM 表名
可以看到剛剛我們的聚合函數(shù)直接用括號(hào)括住了字段。那么現(xiàn)在讓我們來(lái)看一下,樣例如下。
上面的語(yǔ)句中使用了count函數(shù),可以對(duì)搜索到的結(jié)果進(jìn)行計(jì)數(shù),最后我們就可以獲取到搜索到的數(shù)據(jù)的條數(shù)。
下面我們來(lái)學(xué)習(xí)一下max函數(shù),這個(gè)函數(shù)可以將搜索到的結(jié)果的最大值返回出來(lái)作為搜索的結(jié)果。下面我們來(lái)看一下示例。
我們對(duì)人員的年齡進(jìn)行搜索,最后將搜索到的結(jié)果數(shù)據(jù),通過(guò)聚合函數(shù)MAX,求出結(jié)果中的最大值。
然后就是min函數(shù),這個(gè)函數(shù)可以將搜索到的結(jié)果的最小值返回為結(jié)果,跟max恰巧相反。樣例如下。
最后就是avg函數(shù)和sum函數(shù),一個(gè)是求平均值,另一個(gè)是求和,這兩個(gè)的問(wèn)題都不是很大,和前面的操作是一樣的。這里就不再過(guò)多解釋。
分組查詢
SELECT 字段列表 FROM 表名 [WHERE 條件] GROUP BY 分組字段名 [HAVING 分組后過(guò)濾條件]
首先我們可以發(fā)現(xiàn)在這個(gè)語(yǔ)句中,出現(xiàn)了兩種限制條件,一個(gè)是WHERE,另一個(gè)是HAVING。那么這兩個(gè)東西有什么區(qū)別呢?
- 首先,WHERE是在分組操作前進(jìn)行的條件篩選,HAVING是在分組后的再次篩選。
- 其次,WHERE條件篩選時(shí)不可以使用聚合函數(shù)的,HAVING是在可以進(jìn)行聚合函數(shù)篩選的。
那么我們來(lái)舉一個(gè)例子。在公司中,有時(shí)候會(huì)來(lái)進(jìn)行統(tǒng)計(jì),不同年紀(jì)的員工都有多少人。然后進(jìn)行數(shù)據(jù)分析。當(dāng)然我們不需要去做數(shù)據(jù)分析,我們只需要能統(tǒng)計(jì)出來(lái)不同年紀(jì)的員工有多少人就可以了。那么怎么做呢?來(lái)看一下樣例。
上面的樣例中,我們對(duì)年齡進(jìn)行了分組,同時(shí)用聚合函數(shù)進(jìn)行了計(jì)數(shù),但是如果只通過(guò)計(jì)數(shù)進(jìn)行顯示,我們無(wú)法獲取對(duì)應(yīng)的年齡段。所以我們要通過(guò)age進(jìn)行檢索,讓結(jié)果實(shí)現(xiàn)一一對(duì)應(yīng)的效果。
那么假設(shè)我們要想知道男生或者女生的年齡對(duì)應(yīng)關(guān)系呢?其實(shí)就是加一個(gè)where的限制條件就可以了。示例如下。
從這里我們可以看出來(lái),我們的where條件語(yǔ)句會(huì)將我們的搜索結(jié)果優(yōu)先篩選出來(lái),然后再把篩選的結(jié)果進(jìn)行分組。
最后我們來(lái)舉一個(gè)難一點(diǎn)的例子,我們要篩選出所有年齡段中人數(shù)大于1的數(shù)據(jù)。那要如何去篩選。說(shuō)白了就是我們要對(duì)count聚合函數(shù)的結(jié)果進(jìn)行一個(gè)判斷,那么我們可以在group by分組后面寫(xiě)一個(gè)簡(jiǎn)單的having條件判斷語(yǔ)句。下面我們來(lái)看一下例子。
我們來(lái)看一下示例,首先我們將age和count聚合的結(jié)果一起進(jìn)行查詢,同時(shí)將聚合函數(shù)的結(jié)果放入age_count中,再在having中進(jìn)行判斷。得到的結(jié)果就是題目要的數(shù)據(jù)。
排序查詢
排序查詢也是我們生活中非常常用的排序方式,因?yàn)槲覀冊(cè)谀硨?,某東等大的網(wǎng)上商城中,篩選價(jià)格,篩選品牌這些操作,多多多少少涉及到排序算法。那么我們?nèi)绾谓o我們的數(shù)據(jù)進(jìn)行排序呢?我們先來(lái)看一下語(yǔ)法。
SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1, 字段2 排序方式2;
那么排序方式都有哪些呢?
- ASC 升序(默認(rèn)值)
- DESC 降序
但是我們的語(yǔ)法中,有時(shí)候真的會(huì)寫(xiě)好多個(gè)字段的排序方式呀,那怎么辦?
其實(shí)在MySQL中它會(huì)根據(jù)第一個(gè)的排序規(guī)則來(lái)排序,但是如果第一個(gè)字段完全一致,那么我們的電腦會(huì)自動(dòng)根據(jù)我們的下一個(gè)排序字段進(jìn)行排序判斷。所以才會(huì)出現(xiàn)多個(gè)字段的排序問(wèn)題。
那么我們先來(lái)看一個(gè)簡(jiǎn)單的示例,首先我們要獲取到所有學(xué)生的年齡順序,如果年齡相同就看他們的序號(hào)順序來(lái)排列,年齡高的在上面,編號(hào)靠前的在上面。
我們的語(yǔ)句就是這樣的,首先查詢出來(lái)對(duì)應(yīng)的id name age 這三個(gè)字段,然后我們對(duì)age進(jìn)行降序排列,這樣就可以讓年齡大的在前面,但是當(dāng)年齡相同時(shí),我們要進(jìn)行id的升序排列,這樣就可以讓id靠前的在上面了。
分頁(yè)查詢
分頁(yè)查詢就是第幾個(gè)到第幾個(gè)是一頁(yè),后幾個(gè)到后幾個(gè)是第二頁(yè)。其實(shí)就是在一個(gè)范圍內(nèi)進(jìn)行操作的意思。那么他的語(yǔ)句邏輯就是
SELECT 字段列表 FROM 表名 LIMIT 起始索引 查詢記錄數(shù);
那么有幾點(diǎn)時(shí)需要注意的:
- 首先我們每一頁(yè)的起始索引是查詢的頁(yè)碼數(shù)-1后乘上我們的每頁(yè)顯示的數(shù)據(jù)個(gè)數(shù)。
- 如果查詢的是第一頁(yè)數(shù)據(jù)的話,我們可以省略掉起始索引,直接簡(jiǎn)寫(xiě)成limit 記錄數(shù)
那么下面我們來(lái)看一個(gè)示例,首先我們想查表里的數(shù)據(jù),想進(jìn)行分頁(yè),我想5個(gè)數(shù)據(jù)一頁(yè),那么我想看到第一頁(yè)的數(shù)據(jù)。
我們搜索了所有的數(shù)據(jù),因?yàn)槭堑谝豁?yè)所以不需要寫(xiě)起始索引,直接寫(xiě)limit 5就可以了。
那么下一個(gè)問(wèn)題馬上就來(lái)了,如果我想看第二頁(yè)呢?我們繼續(xù)看一下示例部分。
我們現(xiàn)在來(lái)看一下上面的示例,我們要將搜索的結(jié)果進(jìn)行分頁(yè),已知我們要看第二頁(yè)的數(shù)據(jù),那么我們要進(jìn)行一個(gè)計(jì)算,(頁(yè)碼-1)*每頁(yè)的數(shù)據(jù)數(shù)量。這就是我們的起始索引,所以這個(gè)題目中我們的起始索引為5.
執(zhí)行順序
在MySQL中,也是存在執(zhí)行順序的,我們的代碼會(huì)根據(jù)執(zhí)行的順序來(lái)進(jìn)行,而不是從左向右依次執(zhí)行的順序。不難發(fā)現(xiàn),MySQL優(yōu)先執(zhí)行FROM,因?yàn)镕ROM會(huì)知道你要從哪個(gè)表中進(jìn)行操作,在這個(gè)時(shí)候我們就可以給表起一個(gè)別名,方便后續(xù)書(shū)寫(xiě)的時(shí)候太過(guò)于麻煩了,其次WHERE是第二優(yōu)先的,因?yàn)樵诓樵冎?,無(wú)論是分組還是分頁(yè)還是分組后的條件,他們的前提都是數(shù)據(jù)經(jīng)過(guò)了第一輪的篩選,這個(gè)也是合情合理的,之后就是GROUP BY 因?yàn)樵诤Y選之后,進(jìn)行分組讓數(shù)據(jù)更加清晰明了,然后就是在分組后的篩選過(guò)濾,MySQL對(duì)整個(gè)數(shù)據(jù)再一次進(jìn)行過(guò)濾,之后我們才開(kāi)始查找東西,查找到的東西也是通過(guò)前面所有的過(guò)濾得到結(jié)果,得到的結(jié)果再進(jìn)行一個(gè)排序,有需要的進(jìn)行一個(gè)分頁(yè),所以整個(gè)邏輯非常嚴(yán)謹(jǐn)。這就是MySQL的執(zhí)行順序。
函數(shù)
什么是函數(shù)?
函數(shù)是指一段可以直接被另一段程序調(diào)用的程序或代碼。
在一些特定需求時(shí),數(shù)據(jù)庫(kù)表中存儲(chǔ)了一個(gè)人入職當(dāng)天的日期,例如2000-11-12,那么你怎么計(jì)算他入職的天數(shù)呢???
數(shù)據(jù)庫(kù)表中,存儲(chǔ)了學(xué)生的分?jǐn)?shù)值,如99,85,66,那么我們應(yīng)該怎樣做,才可以快速的判定分?jǐn)?shù)等級(jí)呢?
那么這些都是要使用函數(shù)的。這里我們的函數(shù)分為四個(gè)結(jié)算,分別是:
- 字符串函數(shù)
- 數(shù)值函數(shù)
- 日期函數(shù)
- 流程函數(shù)
字符串函數(shù)
MySQL中內(nèi)置了很多的字符串操作函數(shù),但是常用的是下面這幾個(gè)函數(shù)。
我們現(xiàn)在開(kāi)始一個(gè)一個(gè)的看這些函數(shù):
- CONCAT函數(shù) 這個(gè)函數(shù)可以讓多個(gè)字符串進(jìn)行拼接,返回得到的結(jié)果。
- LOWER函數(shù) 熟悉Python的應(yīng)該知道,Python中也有一個(gè)lower函數(shù)。而且他們的作用是相同的,都是將字符串中所有的字符變成小寫(xiě)字符。
- UPPER函數(shù) 可以將字符串中所有的字符全都轉(zhuǎn)化為大寫(xiě)字符。
- LPAD函數(shù) 我們傳入一個(gè)待填充的字符串,預(yù)期的長(zhǎng)度,延伸使用的字符,當(dāng)字符串不滿足這個(gè)長(zhǎng)度時(shí),會(huì)根據(jù)我們傳入的填補(bǔ)使用的字符在字符串的左側(cè)進(jìn)行填充來(lái)將當(dāng)前字符延伸為目標(biāo)長(zhǎng)度。
- RPAD函數(shù) 我們傳入一個(gè)待填充的字符串,預(yù)期的長(zhǎng)度,延伸使用的字符,當(dāng)字符串不滿足這個(gè)長(zhǎng)度時(shí),會(huì)根據(jù)我們傳入的填補(bǔ)使用的字符在字符串的右側(cè)進(jìn)行填充來(lái)將當(dāng)前字符延伸為目標(biāo)長(zhǎng)度。
- TRIM函數(shù) 這個(gè)函數(shù)可以將字符串頭部和尾部的空格刪除。
- SUBSTRING函數(shù) 這個(gè)函數(shù)需要傳入字符串和其實(shí)位置和終止位置,他可以返回這個(gè)區(qū)間的字符串。
現(xiàn)在我們來(lái)看一些例子:
首先是我們的CONCAT函數(shù)的寫(xiě)法,這個(gè)函數(shù)可以將多個(gè)字符串進(jìn)行拼接,所以我們直接做一個(gè)將每一個(gè)用戶的姓名和年齡拼接起來(lái)的函數(shù)。示例如下:
下一個(gè)函數(shù)是LOWER函數(shù),這個(gè)函數(shù)可以將所有字符串中的大寫(xiě)字符變成小寫(xiě)字符,下面我們來(lái)將所有用戶的名字變?yōu)樾?xiě)。大家可以先將數(shù)據(jù)中的一些字符變成大寫(xiě)的,然后測(cè)試代碼。下面是樣例部分。
下面我們來(lái)看一下upper函數(shù),這個(gè)函數(shù)可以將所有的字符轉(zhuǎn)化為大寫(xiě)字符。現(xiàn)在我們實(shí)現(xiàn)一下將所有用戶的名字轉(zhuǎn)化為大寫(xiě)。記得哦!是轉(zhuǎn)化出來(lái),不是之前的搜索。所以我們要使用的是UPDATE函數(shù)。在更新之后我們?cè)賮?lái)搜索一下。
然后是LPAD函數(shù)和RPAD函數(shù),我們首先要知道,他們的作用就是用我們想使用的字符延伸字符串到我們想要的長(zhǎng)度。那么我們可以來(lái)將所有的人員姓名對(duì)齊為3個(gè)字符。下面我們來(lái)看一下示例。
注意事項(xiàng):
當(dāng)我們想要左對(duì)齊的字符數(shù)并不是現(xiàn)有字符串中最大的字符數(shù),例如:我們的數(shù)據(jù)中有的名字是3個(gè)字符的,但是我們想要1個(gè)字符左側(cè)對(duì)齊,就會(huì)出現(xiàn)一個(gè)BUG。我們來(lái)看一下下面的代碼。
我們會(huì)發(fā)現(xiàn)三個(gè)的或者兩個(gè)字符的名字?jǐn)?shù)據(jù),全都被剪切開(kāi)了,所以這個(gè)問(wèn)題是我們要去注意的。
下面我們繼續(xù)學(xué)新的函數(shù),TRIM函數(shù)。這個(gè)函數(shù)可以清除掉字符串的開(kāi)頭和結(jié)尾部分的空格。是一個(gè)很方便的函數(shù)。那么我們現(xiàn)在先用更新函數(shù)將每一個(gè)人的名字前面都加上空格,然后再通過(guò)這個(gè)函數(shù)來(lái)刪除掉他們。然后搜索一遍。示例代碼如下:
最后就是我們的SUBSTRING函數(shù)了,這個(gè)函數(shù)的用處就是將一個(gè)范圍內(nèi)的字符串返回出來(lái),下面我們返回一下,一個(gè)范圍內(nèi)的人員姓名。
我們會(huì)發(fā)現(xiàn)有的用戶名字只有一個(gè)字符,但是我想輸出他兩個(gè)字符,那么也不會(huì)報(bào)錯(cuò)。
數(shù)值函數(shù)
那么我們現(xiàn)在已經(jīng)學(xué)完了字符串的函數(shù),現(xiàn)在讓我們來(lái)學(xué)習(xí)一下什么是數(shù)值的函數(shù)。首先我們看一下下面的表格。
下面我們來(lái)進(jìn)行一下數(shù)值函數(shù)的講解:
- CEIL函數(shù) 可以將數(shù)值向上取整,得到一個(gè)大于當(dāng)前數(shù)值的整數(shù)數(shù)據(jù)
- FLOOR函數(shù) 可以將數(shù)值向下取整,得到一個(gè)小于當(dāng)前數(shù)值的整數(shù)數(shù)據(jù)
- MOD函數(shù) 這個(gè)函數(shù),接受兩個(gè)參數(shù)(x, y),得到的結(jié)果就是x/y的模
- RAND函數(shù) 返回0-1內(nèi)的隨機(jī)數(shù)
- ROUND函數(shù) 函數(shù)接受兩個(gè)參數(shù)(x, y),求參數(shù)x的四舍五入的值,保留y位小數(shù)
上面就是幾個(gè)我們常說(shuō)的函數(shù)。下面我們來(lái)一個(gè)一個(gè)學(xué)習(xí)一下。
首先是CEIL函數(shù),這個(gè)函數(shù)可以進(jìn)行向上取整的操作,那么我們現(xiàn)在在原有數(shù)據(jù)中添加一個(gè)新的字段,人員分?jǐn)?shù),這個(gè)字段是一個(gè)double類型,我們要將他們的分?jǐn)?shù)查詢出來(lái)并進(jìn)行向上取整。先來(lái)看一下示例。
不難看出,上面的示例代碼中,進(jìn)行了搜索,查詢了用戶名稱和他的成績(jī)的向上取整的結(jié)果。
下面就是使用FLOOR函數(shù)的結(jié)果,數(shù)據(jù)進(jìn)行向下取整,可以看一下這個(gè)示例代碼。
可以看到所有的數(shù)值,整體向下取整。
下面我們來(lái)看一下MOD函數(shù),這個(gè)函數(shù)的取模操作,大家一定都知道吧??匆幌孪旅娴氖纠?/p>
可以看到上面的示例中進(jìn)行了,10/3的取模操作。
rand函數(shù)沒(méi)有太多要說(shuō)的,就是一個(gè)取0-1之間的隨機(jī)數(shù)的函數(shù),我們看一下效果。
最后是ROUND函數(shù),是一個(gè)四舍五入的函數(shù)。第一個(gè)參數(shù)為數(shù)值,第二個(gè)參數(shù)為取幾位。
可以看到樣例中,將我們表中的所有分?jǐn)?shù)都進(jìn)行了取一位的操作。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-552059.html
流程函數(shù)
先寫(xiě)到這里吧。。。。等到下一篇文章,我們繼續(xù)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-552059.html
到了這里,關(guān)于MySQL入門(mén)階段這一篇就夠了-學(xué)習(xí)筆記(手敲1.5萬(wàn)字)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!