創(chuàng)建學生表
創(chuàng)建Students和Courses表
CREATE TABLE Students (
StudentID int PRIMARY KEY,
Name varchar(255),
Gender varchar(1),
Age int,
City varchar(255)
);
INSERT INTO Students VALUES(1, 'David', 'M', 21, 'Shanghai');
INSERT INTO Students VALUES(2, 'Kevin', 'M', 19, 'Beijing');
INSERT INTO Students VALUES(3, 'Emily', 'F', 22, 'Shanghai');
INSERT INTO Students VALUES(4, 'William', 'M', 20, 'New York City');
INSERT INTO Students VALUES(5, 'Alice', 'F', 19, 'Los Angeles');
INSERT INTO Students VALUES(6, 'Frank', 'F', 22, 'Los Angeles');
CREATE TABLE Courses (
CourseID int PRIMARY KEY,
CourseName varchar(255)
);
INSERT INTO Courses VALUES(1, 'CS101');
INSERT INTO Courses VALUES(2, 'CS202');
INSERT INTO Courses VALUES(3, 'EE101');
聚合查詢
聚合函數(shù)
直接查詢
SELECT COUNT(*) FROM Students;
設置別名查詢
SELECT COUNT(*) AS StudentsNum FROM Students;
設置條件查詢
使用COUNT(*) 和 COUNT(StudentID)是一樣的效果,因為StudentID是主鍵,每行記錄的主鍵都不同。另外我們在聚合查詢中還是能使用WHERE子句的,比如我們要查找年齡大于20歲的學生數(shù)量,可使用以下SQL語句:
SELECT COUNT(*) FROM Students AS s WHERE s.age > 20;
常用的聚合函數(shù)
函數(shù) 說明
SUM 計算某一列的總和,該列必須為數(shù)值類型
AVG 計算某一列的平均數(shù),該列必須為數(shù)值類型
MAX 計算某一列的最大值
MIN 計算某一列的最小值
查詢學生的平均年齡
SELECT AVG(Age) FROM Students;
使用AVG聚合函數(shù)
分組查詢
單個字段Group by
根據(jù)城市City對學生進行分組,并需要查詢每個城市有多少學生
SELECT City, COUNT(*) FROM Students GROUP BY City;
報錯分組查詢
如果將Name也放入查詢結果,會報錯,因為來自相同城市的學生可能有很多位,名字各不相同,所以以下語句是不合法的:
SELECT City, COUNT(*), Name FROM Students GROUP BY City;
報錯信息如下
SELECT 列表的表達式 #3 不在 GROUP BY 子句中,并且包含非聚合列“tuling.Students.Name”,該列在功能上不依賴于 GROUP BY 子句中的列;這與 sql_mode=only_full_group_by 不兼容。
#3就指的是Name那一列
多字段分組查詢
GROUP BY 也能放入多個字段,比如我們想先將學生根據(jù)City分組,然后再根據(jù)性別分組,可以使用以下語句:
SELECT City, Gender, COUNT(*) FROM Students GROUP BY City, Gender;
學生表中Los Angeles的兩個人性別一樣,分組顯示的為F,計數(shù)為2
現(xiàn)在我將其中一人人的性別改為M,思考一下查詢結果會發(fā)生變化嗎?
地點相同,性別不同的被區(qū)分出來了。
可以看到原來Los Angeles為2,現(xiàn)在變成了兩個1,性別M和F被區(qū)分了。
多表查詢
SELECT 查詢除了能從單表中查數(shù)據(jù)外,也能從多表中查詢數(shù)據(jù)。語法如下:
直接查詢
SELECT * FROM Students, Courses;
查詢結果是兩個表的笛卡爾積
假設Students有5列字段和7行記錄,Courses有2列字段和3行記錄,其結果就是一個擁有21 (3 * 7) 行記錄和 7 (5 + 2) 列字段的二維表,既Students表的每一行和Courses表的每一行兩兩拼在一起。結果集的列數(shù)會是兩表列數(shù)之和,而行數(shù)是兩表行數(shù)之積。
重命名查詢
有時候兩張表可能擁有相同名字的字段,那么結果則會讓人疑惑,我們可以通過使用 AS 取別名來區(qū)別字段。比如使用以下語句給StudentID和CourseID改名為StudentId和CourseId:
SELECT Students.StudentID AS StudentId, Courses.CourseID AS CourseId FROM Students, Courses;
給字段取別名的語法類似 column_name AS new_column_name,上面的語句分別給StudentID和CoursesID取了別名StudentId和CourseId,雖然在這個例子中,我們只是將最后的字母D變?yōu)樾?。但考慮一下另一種情況:假設Students和Courses的主鍵字段都叫ID,那么這個別名就很有幫助了,我們可以使用以下語句使查詢結果更明了:
SELECT Students.ID AS StudentId, Courses.ID AS CourseId FROM Students, Courses;
除了給輸出字段取別名外,給表格取別名也很有用的,語法類似table_name AS alias,我們可以將上面的語句寫成下面這樣:
SELECT S.ID AS StudentId, C.ID AS CourseId FROM Students AS S, Courses AS C;
Students表新建一列CourseID
在多表查詢中,還是能使用WHERE子句。為了幫助大家理解之后的內容,我們需要給Students添加一列新的字段CourseID,代表此學生選擇的課程:
新建一列CourseID在City之后
alter table Students add column CourseID int(4) not null after City;
CouseID的值設置為StudentID的值一半
update Students set CourseID = StudentID/2
查詢StudentID和其對應的課程名字
SELECT S.StudentID,C.CourseName
FROM Students AS S,Courses AS C
WHERE S.CourseID = C.CourseID;
報錯!??! 知道為什么嗎一般 erro syntax就是中文字符的問題,
Students as S,Courses as C 這個逗號是中文字符,改成英文字符后運行成功啦
除了WHERE子句,其他子句類似ORDER BY,GROUP BY也都適用于多表查詢。
除了WHERE子句,其他子句類似ORDER BY,GROUP BY也都適用于多表查詢。
連接(JOIN)查詢
INNER JOIN
連接查詢是另一種類型的多表查詢,連接查詢會對多個表格進行JOIN運算。也就是說,先確定一個主表作為結果集,然后將其他表的記錄有選擇性地“嵌入”到主表結果集上。
假設我們想要知道每個學生選擇的課程名字,除了上面提到的多表查詢加WHERE子句,我們還能使用INNER JOIN子句:
SELECT S.StudentID, C.CourseName
FROM Students AS S
INNER JOIN Courses AS C ON S.CourseID = C.CourseID;
此語句就能將每個StudentID和其對應的課程名查詢出來,要注意INNSER JOIN語句的內在執(zhí)行過程如下:
- 1 確定主表,使用 FROM table_name
- 2 緊接著確認連接的表,使用 INNER JOIN table_name
- 3 再確定連接條件,使用 ON condition,上面語句的條件就是 S.CourseID = C.CourseID
- 4 最后還能加上 : WHERE、ORDER BY等子句
除了INNER JOIN外,我們還有LEFT JOIN, RIGHT JOIN, 和FULL JOIN。
補充:別名不是必須的,只是為了增加可讀性。
RIGHT JOIN, LEFT JOIN
如果我們將語句改為 RIGHT JOIN:
SELECT S.StudentID, C.CourseName
FROM Students AS S
RIGHT JOIN Courses AS C ON S.CourseID = C.CourseID;
修改Students表格,讓5,6選課程1,重新右連接查詢。
執(zhí)行上面的語句之后,如果有一節(jié)課沒有任何學生加入,我們會有一行多余的記錄,記錄中僅有CourseName,但是StudentID為NULL。
為什么會這樣呢?INNER JOIN 會返回同時存在兩張表的數(shù)據(jù),如果Students有1, 2, 3, 5課號,Courses也有1, 2, 3, 4課號,那么結果就是其相交集1, 2, 3。而 RIGHT JOIN 返回的則是右表存在的記錄,如果左表不存在右表中的某幾行,那結果中的那幾行就會是NULL。
而 LEFT JOIN 則會返回左表中都存在的數(shù),如果給Students加上CourseID=10,即使Courses表中沒有ID為10的課程記錄,那么LEFT JOIN的結果還是會多一行記錄,其對應的CourseName是NULL。(補充:LEFT JOIN 在有些數(shù)據(jù)庫中叫做 LEFT OUT JOIN,同理 RIGHT JOIN 也可能叫做 RIGHT OUT JOIN。)
FULL JOIN
最后一種 JOIN 是 FULL JOIN,結果集會把兩張表的所有記錄全部選出來,并自動把兩張表中不存在的列補充為NULL。
為了幫助大家理解連接查詢的邏輯,大家可以參看以下的圖示,左邊的圓可以理解為左表,右邊的圓可以理解為右表。
以上就是SQL語法的基本教程啦,現(xiàn)在大家已經(jīng)學會了如何使用 SQL 創(chuàng)建表格和記錄,并使用高級的 SQL 語句進行復雜的查詢,下一章我們就開始學習使用真正的數(shù)據(jù)庫軟件 MySQL。
課后練習
請寫出SQL語句,找出加入CourseID為1的學生數(shù)量和課程名字,要注意的是,我們只尋找那些年紀大于20歲的男學生數(shù)量。
方法1 使用Where
SELECT COUNT(*) AS StudentsNum,CourseName
FROM Students AS S,Courses AS C
WHERE S.CourseID = C.CourseID AND S.CourseID = 1 AND S.Age > 20 AND S.Gender = 'M';
方法2 Group by + where文章來源:http://www.zghlxwxcb.cn/news/detail-697764.html
SELECT COUNT(*) AS StudentsNum, CourseName
FROM Students LEFT JOIN Courses ON Students.CourseID = Courses.CourseID
WHERE Students.Age > 20 AND Students.Gender = 'M'
GROUP BY Students.CourseID;
復習
- 1 確定主表,使用 FROM table_name
- 2 緊接著確認連接的表,使用 INNER JOIN table_name
- 3 再確定連接條件,使用 ON condition,上面語句的條件就是 S.CourseID = C.CourseID
- 4 最后還能加上 : WHERE、ORDER BY等子句
除了INNER JOIN外,我們還有LEFT JOIN, RIGHT JOIN, 和FULL JOIN。
參考
【SQL高級查詢語句:聚合查詢,多表查詢,連接查詢【關系數(shù)據(jù)庫SQL教程5】】 https://www.bilibili.com/video/BV1Zp4y1Q7mj/?share_source=copy_web&vd_source=fe6c23f6f1353ed1eff5d5e866171572文章來源地址http://www.zghlxwxcb.cn/news/detail-697764.html
到了這里,關于數(shù)據(jù)庫 SQL高級查詢語句:聚合查詢,多表查詢,連接查詢的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!