練習(xí)鏈接
1 查詢所有數(shù)據(jù)
查詢students表的所有數(shù)據(jù)
SELECT * FROM students;
SELECT可以用作計(jì)算旧困,直接計(jì)算出表達(dá)式的結(jié)果审胸,但它并不是SQL的強(qiáng)項(xiàng)卓缰。
但是不帶FROM子句的SELECT語(yǔ)句蛛株,可用來(lái)判斷當(dāng)前到數(shù)據(jù)庫(kù)的連接是否有效抓半。
許多檢測(cè)工具會(huì)執(zhí)行一條SELECT 1扔字,來(lái)測(cè)試數(shù)據(jù)庫(kù)連接囊嘉。
2 條件查詢
1)查詢分?jǐn)?shù)在80分以上的學(xué)生記錄温技。
SELECT * FROM students WHERE score >= 80;
2)符合條件“分?jǐn)?shù)在80分或以上”,并且還符合條件“男生”
SELECT * FROM students WHERE score >= 80 AND gender = 'M';
3)符合條件“分?jǐn)?shù)在80分或以上”或者“男生”
SELECT * FROM students WHERE score >= 80 OR gender = 'M';
4)符合條件“不是2班的學(xué)生”扭粱,NOT查詢不是很常用
SELECT * FROM students WHERE NOT class_id = 2;
5)分?jǐn)?shù)在80以下或者90以上舵鳞,并且是男生
SELECT * FROM students WHERE (score < 80 OR score > 90) AND gender = 'M';
NOT優(yōu)先級(jí)最高,其次是AND琢蛤,最后是OR蜓堕。加上括號(hào)可以改變優(yōu)先級(jí)。
3 投影查詢
1)只希望返回某些列的數(shù)據(jù)博其,而不是所有列的數(shù)套才;
例如,從students表中返回id慕淡、score和name這三列:
SELECT id, score, name FROM students;
2)還可以給每一列起個(gè)別名背伴,這樣,結(jié)果集的列名就可以與原表的列名不同峰髓。
例如傻寂,以下SELECT語(yǔ)句將列名score重命名為points,而id和name列名保持不變:
SELECT id, score points, name FROM students;
4 排序
查詢結(jié)果集通常是按照id排序的携兵,也就是根據(jù)主鍵排序疾掰。
1)加上ORDER BY子句,改為其他條件排序徐紧,例如按照成績(jī)從低到高進(jìn)行排序:
SELECT id, name, gender, score FROM students ORDER BY score;
2)如要反過(guò)來(lái)静檬,按照成績(jī)從高到底排序,末尾加上DESC表示“倒序”:
SELECT id, name, gender, score FROM students ORDER BY score DESC;
3)如果score列有相同數(shù)據(jù)并级,進(jìn)一步排序巴柿,可以繼續(xù)添加列名。
例如死遭,使用ORDER BY score DESC, gender表示先按score列倒序广恢,如果有相同分?jǐn)?shù)的,再按gender列排序:
SELECT id, name, gender, score FROM students ORDER BY score DESC, gender;
4)有WHERE子句呀潭,ORDER BY要放到WHERE后钉迷。
例如,查詢一班的學(xué)生成績(jī)钠署,并按照倒序排序:
SELECT id, name, gender, score
FROM students
WHERE class_id = 1
ORDER BY score DESC;
5 分頁(yè)查詢
SELECT查詢時(shí)糠聪,如幾萬(wàn)行數(shù)據(jù),一個(gè)頁(yè)面顯示數(shù)據(jù)量太大谐鼎,不如分頁(yè)顯示舰蟆,每次顯示100條。
步驟如下:
1)我們先把所有學(xué)生按照成績(jī)從高到低進(jìn)行排序:
SELECT id, name, gender, score FROM students ORDER BY score DESC;
2)把結(jié)果集分頁(yè),每頁(yè)3條記錄身害。
查詢第1頁(yè)記錄味悄,可以使用LIMIT 3 OFFSET 0:
SELECT id, name, gender, score
FROM students
ORDER BY score DESC
LIMIT 3 OFFSET 0;
如果要查詢第2頁(yè),需要“跳過(guò)”頭3條記錄塌鸯。(每頁(yè)記錄條數(shù)* (頁(yè)碼 - 1))
也就是對(duì)結(jié)果集從3號(hào)記錄開(kāi)始查詢侍瑟,把OFFSET設(shè)定為3:
SELECT id, name, gender, score
FROM students
ORDER BY score DESC
LIMIT 3 OFFSET 3;
如果原本記錄集一共就10條記錄,但我們把OFFSET設(shè)置為20丙猬,顯示結(jié)果如下:
Empty result set
OFFSET超過(guò)了查詢的最大數(shù)量并不會(huì)報(bào)錯(cuò)涨颜,而是得到一個(gè)空的結(jié)果集。
6 聚合查詢
統(tǒng)計(jì)一張表的數(shù)據(jù)量茧球,例如庭瑰,想查詢students表一共有多少條記錄:
SELECT COUNT(*) FROM students;
通常,使用聚合查詢時(shí)抢埋,我們應(yīng)該給列名設(shè)置一個(gè)別名弹灭,便于處理結(jié)果:
SELECT COUNT(*) num FROM students;
除了COUNT()函數(shù)外,SQL還提供了如下聚合函數(shù):
分組聚合
SQL還提供了“分組聚合”的功能羹令,按class_id分組:
SELECT COUNT(*) num FROM students GROUP BY class_id;
可以把class_id列也放入結(jié)果集中鲤屡,便于查看班級(jí):
SELECT class_id, COUNT(*) num FROM students GROUP BY class_id;
聚合查詢的列中,只能放入分組的列。
并沒(méi)有按照name分類福侈,以下報(bào)錯(cuò):
SELECT name, class_id, COUNT(*) num FROM students GROUP BY class_id;
也可以使用多個(gè)列進(jìn)行分組酒来。
例如,我們想統(tǒng)計(jì)各班的男生和女生人數(shù):
SELECT class_id, gender, COUNT(*) num FROM students GROUP BY class_id, gender;
7?多表查詢
1) SELECT可以從多張表同時(shí)查詢數(shù)據(jù)肪凛。
例如堰汉,同時(shí)從students表和classes表的“乘積”,又稱笛卡爾查詢:
SELECT * FROM students, classes;
以上為students表的每一行,與classes表的每一行伟墙,兩兩拼在一起返回翘鸭。
結(jié)果集列數(shù) = students列數(shù) + classes列數(shù)
結(jié)果集行數(shù) = students行數(shù) * classes行數(shù)
2) 上述結(jié)果集有兩列id和兩列name,不好區(qū)分戳葵。
要解決這個(gè)問(wèn)題就乓,可以利用投影查詢的“設(shè)置列的別名”來(lái)給兩個(gè)表各自的id和name列起別名:
SELECT
? ? students.id sid,
? ? students.name,
? ? students.gender,
? ? students.score,
? ? classes.id cid,
? ? classes.name cname
FROM students, classes;
SQL還允許給表設(shè)置一個(gè)別名,讓我們?cè)谕队安樵冎幸闷饋?lái)稍微簡(jiǎn)潔一點(diǎn):
SELECT
? ? s.id sid,
? ? s.name,
? ? s.gender,
? ? s.score,
? ? c.id cid,
? ? c.name cname
FROM students s, classes c;
多表查詢也是可以添加WHERE條件的拱烁,我們來(lái)試試:
SELECT? ??
? ??s.id sid,
? ? s.name,
? ? s.gender,
? ? s.score,
? ? c.id cid,
? ? c.name cname
FROM students s, classes c
WHERE s.gender = 'M' AND c.id = 1;
8 連接查詢
連接查詢對(duì)多個(gè)表進(jìn)行JOIN運(yùn)算生蚁。
先確定一個(gè)主表作為結(jié)果集,然后把其他表的行戏自,有選擇性地“連接”在主表結(jié)果集上邦投。
例如,我們想要選出students表的所有學(xué)生信息擅笔,可以用一條簡(jiǎn)單的SELECT語(yǔ)句完成:
SELECT s.id, s.name, s.class_id, s.gender, s.score FROM students s;
上面的結(jié)果集只有class_id列志衣,缺少對(duì)應(yīng)班級(jí)的name列屯援。
存放班級(jí)名稱的name列存儲(chǔ)在classes表中,
需要根據(jù)students表的class_id念脯,找到classes表對(duì)應(yīng)的行的name列狞洋,就可得班級(jí)名稱。
此時(shí)可通過(guò) 內(nèi)連接——INNER JOIN來(lái)實(shí)現(xiàn):
SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score
FROM students s
INNER JOIN classes c
ON s.class_id = c.id;
有內(nèi)連接(INNER JOIN)就有外連接(OUTER JOIN)和二。
我們把內(nèi)連接查詢改成外連接查詢:
SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score
FROM students s
RIGHT OUTER JOIN classes c
ON s.class_id = c.id;
效果如下:
多出來(lái)的一行“四班”徘铝,但是耳胎,學(xué)生相關(guān)的列如name惯吕、gender、score都為NULL怕午。
這也容易理解废登,因?yàn)楦鶕?jù)ON條件s.class_id = c.id,classes表的id=4的行正是“四班”郁惜,但是堡距,students表中并不存在class_id=4的行。
此外有?LEFT OUTER JOIN兆蕉,以及?FULL OUTER JOIN羽戒。它們的區(qū)別是:
1. INNER JOIN只返回同時(shí)存在于兩張表的行數(shù)據(jù)。
由于students表的class_id包含1虎韵,2易稠,3,classes表的id包含1包蓝,2驶社,3,4测萎,所以亡电,INNER JOIN根據(jù)條件s.class_id = c.id返回的結(jié)果集僅包含1,2硅瞧,3份乒。
2. RIGHT OUTER JOIN返回右表都存在的行。
如果某一行僅在右表存在腕唧,那么結(jié)果集就會(huì)以NULL填充剩下的字段或辖。
3. LEFT OUTER JOIN則返回左表都存在的行。
如果我們給students表增加一列四苇,并添加class_id=5孝凌,由于classes表并不存在id=5的列,所以月腋,LEFT OUTER JOIN的結(jié)果會(huì)增加一列蟀架,對(duì)應(yīng)的class_name是NULL.
4.?FULL OUTER JOIN瓣赂,它會(huì)把兩張表的所有記錄全部選擇出來(lái)。
并且片拍,自動(dòng)把對(duì)方不存在的列填充為NULL煌集。