SQL是數(shù)據(jù)庫的查詢語言,今天我們來學(xué)習(xí)一下。文章的語句都是在Navicat premium的query界面運行的,使用的數(shù)據(jù)庫是mysql,具體的軟件安裝使用可自行百度。
為了有數(shù)據(jù)演示,我這里創(chuàng)建了一個school的數(shù)據(jù)庫,里面包括四張表,詳細內(nèi)容如下截圖,我是先在Excel里面創(chuàng)建了數(shù)據(jù),然后導(dǎo)入數(shù)據(jù)庫的,如果想要數(shù)據(jù)可在后臺回復(fù)“SQL”。
一、檢索語句
select column from table
table是表名,上圖中的course、sc、student、teacher;column是我們要查詢的字段/列,如果用通配符*代替就是獲取所有的字段。
這里只顯示運行了 select * from sc這條語句。
其實在運行select cid from sc這條語句的時候會發(fā)現(xiàn)結(jié)果是返回了所有的cid,但這些cid有許多重復(fù)的,如果想要獲得唯一的cid只需要distinct關(guān)鍵詞就可以了。
二、過濾數(shù)據(jù)
WHERE子句
1、單條件篩選
學(xué)號為1000的同學(xué)的所有成績
2、多條件篩選
學(xué)號1000和課程編號8的課程成績
3、AND、OR、()三者運算級
學(xué)號為1000同學(xué)的編號8或者編號31兩門課的成績
因為成績表里面課程編號最高是到30的,所以學(xué)生1000是沒有學(xué)cid=31的這門課的,只得到一條結(jié)果,這里的()的運算優(yōu)先級是高于and高于or的,如果沒有括號的話,就先執(zhí)行and,返回結(jié)果為空,最終返回cid=8所有學(xué)生的成績了。
4、IN操作符
學(xué)號為1000同學(xué)的課程編號3或6或9或14或31的成績
如果用or語句的話整條查詢語句就會非常長,但是用IN就會簡潔很多。IN操作符是用來指定條件范圍,范圍中的每個條件都可以進行匹配,IN的執(zhí)行要比or更快,而且IN是可以包含select子句的,使得可以動態(tài)的建立WHERE子句。
5、NOT操作符——否定它之后所跟的任何條件
cid一共是30個,排除了括號里面的四個剩下26個。
6、操作符:=、<>、!=、<、 <= 、> 、>= 、between
7、通配符過濾
LIKE操作符
百分號(%)通配符:表示任何字符出現(xiàn)任意次數(shù)
下劃線(_)通配符:只匹配單個字符
對比兩個結(jié)果可以發(fā)現(xiàn)%返回了'zhang'之后兩個字母和三個字母的姓名結(jié)果
'__'這里是用了兩個'_',因為一個的結(jié)果為空,兩個就只返回了'zhang'之后兩個字母的結(jié)果。
通配符雖然比較有用,但是他的搜索速度要比其他搜索要慢,而且除非絕對有必要,否則不要把通配符放在搜索模式的開始處,因為這樣搜索起來是最慢的。
三、排序數(shù)據(jù)
1、ORDER BY
得到數(shù)據(jù)并按score排序,默認的是升序,如果要降序加一個DESC關(guān)鍵字就可以了。
如果是對多個列排序只需要把相應(yīng)的列放在order by后面就可以了,而DESC關(guān)鍵字只應(yīng)用到直接位于其前面的列名。
如圖先按score排序,但是由于desc只作用在cid上面,所以score是默認的升序,而cid則是在score相同的情況是降序排序。
2、LIMIT
可以對比上一張發(fā)現(xiàn)我們的結(jié)果是這個學(xué)生成績排名第三到第七的結(jié)果,limit的第一個參數(shù)表示從第幾個位置開始,計數(shù)是從0開始,所以2得到的結(jié)果是從第三行開始,如果省略表示從0開始,第二個參數(shù)表示返回記錄行的最大數(shù),這里寫的是5,如果結(jié)果只有3行就只返回3行。
同時在mysql里面是使用limit,但是在SqlServer里是用top,Oracle則是用rownum。
四、匯總分組數(shù)據(jù)
聚合函數(shù)有五個,分別是count、sum、avg、max、min,作用分別是計數(shù)、求和、求平均、最大值、最小值。
分組是group by函數(shù),得到的結(jié)果類似Excel的數(shù)據(jù)透視表。
接下來說一下聚合函數(shù)和分組需要注意的地方。
1、count有兩種用法
count(*)對表中行的數(shù)據(jù)進行計算,即使表中包含空值也會被計數(shù)。
count(column)對特定列中有值得行進行計數(shù),忽略NULL值。
2、group by子句可以包含任意數(shù)目的列,這使得能對分組嵌套。
3、group by子句中的列必須是檢索列或者有效的表達式,不能是聚合函數(shù)。
4、除聚合函數(shù)外,select語句中的每個列都必須在group by子句中給出。
5、having支持所有where操作符,差別是where過濾行,having過濾分組。
五、條件判斷
1、IF
SQL中的IF使用和Excel里面的差不多,可以用于條件判斷,也可以用于存儲過程的流程控制。
2、CASE WHEN
圖中兩段SQL語句得到的結(jié)果和上面IF得到的結(jié)果是一樣的,但是兩個case語句里面ssex的位置有區(qū)別,第一種就是簡單的case函數(shù)寫法,第二種是case搜索函數(shù)寫法。
我們還可以用select和case完成二維表的輸出形式,實現(xiàn)數(shù)據(jù)透視表的功能。
六、子查詢和聯(lián)結(jié)表
之前的操作都是基于一張表的,但是實際工作中會有很多張表,而且你需要的數(shù)據(jù)不會全部都在一張表里面,這時候就需要操作多張表來獲取數(shù)據(jù)了。
比如想查詢沒有學(xué)過某位老師的學(xué)生學(xué)號和姓名,這時就需要在多張表里面去獲取數(shù)據(jù)。
這里我們可以先建一個查詢獲得學(xué)過這個老師課程的學(xué)生的學(xué)號的子查詢,然后在這個的基礎(chǔ)上再去獲取沒有學(xué)過這位老師課程的學(xué)生學(xué)號和姓名。
再比如要獲取學(xué)生的學(xué)號、姓名、選課數(shù)、總成績,這時也是需要多張表操作的。
這時有兩種處理方式,一種是聯(lián)結(jié)表的方式,我們可以把需要的表通過限定的列名來關(guān)聯(lián),比如這里的student.sid和sc.sid,另一種是利用join合并表的方式,把需要的數(shù)據(jù)從多張表合并到一張表,然后再進行相關(guān)的操作。
這里的join有right、left、inner、outer幾種用法,類似于數(shù)學(xué)的交集和并集運算,這里找了一張圖供參考:
然后就是為什么我們這里寫的left join,實際上這里不管是left還是right或者inner結(jié)果都一樣,因為我們的student.sid和sc.sid是一樣的,但是選擇left是因為student的sid肯定是完整的,有學(xué)生可能沒選課,那他在sc表中是沒有數(shù)據(jù)的,用left之后如果為空是同樣會返回的,從而不會漏掉。
七、視圖
視圖是虛擬的表,與包含數(shù)據(jù)的表不一樣,視圖只包含使用時動態(tài)檢索數(shù)據(jù)的查詢。
如果查詢一位老師教的課程里學(xué)生的學(xué)號、姓名、課程名稱、學(xué)生成績,可以通過表聯(lián)結(jié)來查詢。
但是如果這項操作需要經(jīng)常使用,比如要經(jīng)常查不同老師帶的學(xué)生成績情況,不停的寫SQL就比較麻煩,這時就可以用視圖了,把學(xué)生學(xué)號、姓名、課程名稱、成績、老師名字放在視圖里,這樣下次查詢的時候只需要簡單SELECT語句就可以獲取到數(shù)據(jù)了。
當(dāng)你創(chuàng)建好視圖的時候在左邊的VIEWS下面是有你創(chuàng)建的視圖,當(dāng)然如果不用了也可以刪除的。
視圖重用SQL語句,同時簡化復(fù)雜的SQL操作,使用的時候只是使用表的組成部分而不是整張表,可以給用戶授予表的特定部分的訪問權(quán)限而不是整個表的訪問權(quán)限,從而能保護數(shù)據(jù)。創(chuàng)建好視圖之后可以進行SELECT操作,過濾和排序數(shù)據(jù),將視圖聯(lián)結(jié)到其他的視圖或表。
八、存儲過程
之前的需求都可以用一條SQL語句來完成,但實際上有許多需求一條SQL語句是無法完成的,這時就需要存儲過程,存儲過程簡單來說,就是為完成某個特定功能的SQL語句集,經(jīng)編譯后存儲在數(shù)據(jù)庫中,用戶通過指定存儲過程的名字并給定參數(shù)來調(diào)用執(zhí)行它。
存儲過程把處理封裝在一個單元中,簡化復(fù)雜的操作,同時保證了數(shù)據(jù)的完整性并防止出錯,而且要比使用單獨的SQL語句要快。以上就是存儲過程的簡單、安全、高性能的好處,但存儲過程的編寫要比SQL語句復(fù)雜,就需要更高的技能和更豐富的經(jīng)驗了。
1、創(chuàng)建不帶參數(shù)的存儲過程
以上是創(chuàng)建存儲過程的兩種方式,一種是通過CREATE PROCEDURE語句創(chuàng)建,這里創(chuàng)建了一個名為stu_avg_score的存儲過程,雖然這里沒有參數(shù),但是后面的()是必須要有的,通過CALL調(diào)用就可以得到結(jié)果了,本例中的為 CALL stu_avg_score()。另外一種方式是通過新建函數(shù)功能來創(chuàng)建,不過這里Type類型要選擇PROCEDURE而不是FUCTION,然后按照流程把對應(yīng)的內(nèi)容填上就可以了,點擊Execute在Result里面查看結(jié)果,也可以用CALL調(diào)用。這里BEGIN和END語句用來限定存儲過程體,過程體本身僅是一條簡單的SQL語句。
2、創(chuàng)建帶參數(shù)的存儲過程
三種參數(shù):
IN:輸入?yún)?shù),表示調(diào)用者向過程傳入值(傳入值可以是字面量或變量)
OUT:輸出參數(shù),表示過程向調(diào)用者傳出值(可以返回多個值)(傳出值只能是變量)
INOUT:輸入輸出參數(shù),既表示調(diào)用者向過程傳入值,又表示過程向調(diào)用者傳出值(值只能是變量)
這里s1是需要輸入的參數(shù),是學(xué)生的學(xué)號,然后返回的ccount得到的是學(xué)生的選課數(shù),在CALL調(diào)用的時候變量ccount要加@,調(diào)用時是不顯示數(shù)據(jù)的,所以可以用select選擇顯示。
也可以用函數(shù)生成的形式來,只需要在對應(yīng)的地方填上語句或者參數(shù)就可以了,可以直接執(zhí)行,也可以用CALL調(diào)用生成結(jié)果。
這里只是展示了存儲過程的創(chuàng)建和使用以及一些注意事項,它的實際功能比這些要復(fù)雜和強大的多,還需要實戰(zhàn)中去體會和學(xué)習(xí)。