MySQL筆記4:DQL 查詢資料
阿新 • • 發佈:2022-05-17
4. DQL 查詢資料(最重要)
4.1 DQL
Data Query Language:資料查詢語言
- 所有的查詢操作,Select,簡單的查詢、複雜的查詢
- 資料庫中最核心的語言,最重要的語句
- 使用頻率最高的語句
SELECT完整語法
SELECT [ALL | DISTINCT] {* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]} FROM table_name [as table_alias] [left | right | inner join table_name2] -- 聯合查詢 [WHERE ...] -- 指定結果需滿足的條件 [GROUP BY ...] -- 指定結果按照哪幾個欄位來分組 [HAVING] -- 過濾分組的記錄必須滿足的次要條件 [ORDER BY ...] -- 指定查詢記錄按一個或多個條件排序 [LIMIT {[offset,]row_count | row_countOFFSET offset}]; -- 指定查詢的記錄從哪條至哪條
[]:可選;{}:必選
4.2 指定欄位查詢
查詢
語法:SELECT 欄位, ... FROM 表
-- 查詢全部學生 select 欄位 from 表
SELECT * FROM student
-- 查詢指定欄位
SELECT `StudentNo`,`StudentName` FROM student
別名
當結果不是那麼見名知意時,使用as
起別名
-- 別名,給結果起名字 as:可以給欄位和表起別名 SELECT `StudentNo` AS 學號,`StudentName` AS 學生姓名 FROM student AS s -- 函式 concat(a,b)拼接字串 SELECT CONCAT('姓名:',studentName) AS 新名字 FROM student
去重
去除select查詢出的重複資料,重複的資料只取一條
-- 查詢有考試成績的人
SELECT * FROM result -- 查詢全部考試成績
-- 查詢有參與考試的人
SELECT `StudentNo` FROM result
-- 對重複資料去重
SELECT DISTINCT `StudentNo` FROM result
資料庫的列查詢(表示式)
資料庫中的表示式:文字值、列、Null、函式、計算表示式、系統變數……
select 表示式 from 表
-- 查詢系統版本號(函式) SELECT VERSION() -- 計算(表示式) SELECT 100*3-1 AS 計算結果 -- 查詢自增步長(變數) SELECT @@auto_increment_increment -- 所有考試成績+1分檢視 SELECT `StudentNo`,`StudentResult` FROM result SELECT `StudentNo`,`StudentResult`,`StudentResult`+1 AS 提分後 FROM result
4.3 where條件子句
用於減少符合條件的值。
搜尋的條件由一個或多個表示式組成,結果返回布林值
4.3.1 邏輯運算子
運算子 | 語法 | 描述 |
---|---|---|
and, && | a and b, a && b | 邏輯與,兩個都為真時結果為真 |
or, || | a or b, a||b | 邏輯或,兩個有一個為真時結果為真 |
not, ! | not a, ! a | 邏輯非,取反,真為假,假為真 |
邏輯與
-- 查詢成績在95~100間的人
SELECT `StudentNo`,`StudentResult` FROM result
WHERE `StudentResult`>=95 AND `StudentResult`<=100
-- and, &&
SELECT `StudentNo`,`StudentResult` FROM result
WHERE `StudentResult`>=95 && `StudentResult`<=100
-- 模糊查詢(區間)between...and
SELECT `StudentNo`,`StudentResult` FROM result
WHERE `StudentResult` BETWEEN 95 AND 100
邏輯非
-- 除了學號為1000外的其他學生的成績
SELECT `StudentNo`,`StudentResult` FROM result
WHERE `StudentNo` != 1000
-- not
SELECT `StudentNo`,`StudentResult` FROM result
WHERE NOT `StudentNo` = 1000
4.3.2 模糊查詢:比較運算子
運算子 | 語法 | 描述 |
---|---|---|
IS NULL | a is null | 如果內容為NULL,結果為真 |
IS NOT NULL | a is not null | 如果內容不為NULL,結果為真 |
BETWEEN | a between b and c | 若a在b和c之間,結果為真 |
LIKE | a like b | SQL匹配,如果a匹配b,結果為真 |
IN | a in (a1, a2, a3, ...) | 如果a為a1, a2, a3, ...中的某一個值,結果為真 |
LIKE
like結合符號
-
%
:代表0到任一個字元 -
_
:代表一個字元
-- 查詢名字以'張'開頭的人
-- like結合 %(代表0到任一個字元) _(一個字元)
SELECT `StudentNo`, `StudentName` FROM `student`
WHERE `StudentName` LIKE '張%'
-- 查詢'張'後面只有一個字的人
SELECT `StudentNo`, `StudentName` FROM `student`
WHERE `StudentName` LIKE '張_'
-- 查詢'張'後面兩個字的
SELECT `StudentNo`, `StudentName` FROM `student`
WHERE `StudentName` LIKE '張__'
-- 查詢名字裡有'張'的人
SELECT `StudentNo`, `StudentName` FROM `student`
WHERE `StudentName` LIKE '%張%'
IN
使用IN
進行查詢需要使用完全匹配的字元(可以通過巢狀進行模糊查詢)
-- 查詢1001,1002,1003號學生
SELECT `StudentNo`, `StudentName` FROM `student`
WHERE `StudentNo` IN (1001, 1002, 1003);
-- 查詢地址在北京的人
-- 只寫部分(如'北京',無法查詢,需要使用具體的位置,如('北京朝陽')
SELECT `StudentNo`, `StudentName`,`Address` FROM `student`
WHERE `Address` IN ('北京朝陽');
NULL, IS NULL
NULL
與IS NULL
字元查詢使用的是允許為空時的空字元。在預設內容不為空時填充的空內容''
無法進行查詢。
-- 查詢地址為空的學生 null, ''
SELECT `StudentNo`, `StudentName`,`Address` FROM `student`
WHERE `Address` = '' OR `Address` IS NULL;
-- 查詢地址不為空的人(預設不為空時,會自動填入'',此時無法用null語句排除
-- 生日為空時能查出正確內容,推測是建立表格時設定的原因
SELECT `StudentNo`, `StudentName`,`Address` FROM `student`
WHERE `Address` IS NOT NULL;
-- 查詢生日為空的人
SELECT `StudentNo`, `StudentName`,`BornDate` FROM `student`
WHERE `BornDate` IS NULL;
4.4 聯表查詢 join on
-
join on
:連線查詢,jion 連線的表 on 判斷的條件
-
where
:等值查詢
七種JOIN理論:MySQL中沒有full outer join操作,因此在MySQL中,6 = 1 union 4; 7 = 2 union 5
-
inner join
:用於查詢兩表都有的資料(共同的部分,類似交集) -
left join
:用於查詢左邊部分(student)中的資料(即使右邊沒有) -
right join
:用於查詢右邊部分(result)中的資料(即使左邊沒有)
-- 查詢參加了考試的同學(學號,姓名,科目編號,分數)
SELECT * FROM student
SELECT * FROM result
/*
思路:
1. 分析需求,分析查詢欄位的來源表,來自不同表時使用連線查詢
2. 確定使用哪種連線查詢
3. 確定交集(兩個表中哪些資料相同,判斷條件)
*/
-- inner join用於查詢兩表相交部分中的資料
SELECT s.`StudentNo`,`StudentName`,`StudentResult`
FROM `student` AS s
INNER JOIN `result` AS r
ON s.`StudentNo` = r.`StudentNo`;
-- left join用於查詢左邊部分(student)中的資料(即使右邊沒有)
SELECT s.`StudentNo`,`StudentName`,`StudentResult`
FROM `student` AS s
LEFT JOIN `result` AS r
ON s.`StudentNo` = r.`StudentNo`;
-- right join用於查詢右邊部分(result)中的資料(即使左邊沒有)
SELECT s.`StudentNo`,`StudentName`,`StudentResult`
FROM `student` AS s
RIGHT JOIN `result` AS r
ON s.`StudentNo` = r.`StudentNo`;
多張表聯表查詢
按順序找交集,依次聯結多張表
-- 查詢參加考試的同學資訊:學號,姓名,科目名,分數(3表查詢)
/*
1. 來源表,student, result, subject
2. 基準,參加考試的學號,result表中的學號
3. 將第一次查詢出的結果,再次進行連線查詢
*/
SELECT r.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `student` AS s
RIGHT JOIN `result` AS r
ON r.`StudentNo` = s.`StudentNo`
LEFT JOIN `subject` AS sub -- 連線第三張表
ON r.`SubjectNo` = sub.`SubjectNo`
自連線(瞭解)
自己的表和自己的表連線,核心:一張表拆成兩張一樣的表
例表:categoryid為表示自己的序號,pid為父id,關係如下圖所示。
-- 查詢父子資訊:把一張表視為兩張相同的表
-- a和b是同一張表的兩個別名,將同一張表當作兩張表,進行資訊的查詢
SELECT a.`categoryName` AS 'parent', b.`categoryName` AS 'kid'
FROM `category` AS a, `category` AS b
WHERE a.`categoryid` = b.`pid`
4.5 分頁和排序
排序 order by
排序: 升序ASC 降序DESC
ORDER BY 列名 ASC -- 升序
ORDER BY 列名 DESC -- 降序
SELECT `StudentName`,`IdentityCard`
FROM `student`
ORDER BY `StudentNo` ASC
分頁 limit
分頁的作用:緩解資料庫壓力,增加體驗
-- 分頁,每頁顯示3條資料
-- 語法: limit 起始值,頁面長度pagesize
SELECT `StudentName`,`IdentityCard`
FROM `student`
ORDER BY `StudentNo` ASC
LIMIT 0,3 -- 從0開始,顯示3條
應用
-- 查詢高等數學第一學年 課程成績排名前10,且分數大於等於80的學生資訊(學號,姓名,課程名稱,分數)
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `student` AS s
RIGHT JOIN `result` AS r
ON s.`StudentNo` = r.`StudentNo`
INNER JOIN `subject` AS sub
ON r.`SubjectNo` = sub.`SubjectNo`
WHERE `StudentResult`>=80 && `SubjectName`='高等數學-1'
ORDER BY `StudentResult` DESC
LIMIT 0,10
4.6 子查詢
使where語句查詢的不是固定的
本質:在where語句中巢狀一個子查詢語句
例1 :連線查詢+子查詢
查詢資料庫結構-1的所有考試結果(學號、科目名字、成績),降序
-- 1.查詢資料庫結構-1的所有考試結果(學號、科目名字、成績),降序
-- 方法1:使用連線查詢
-- 方法2:使用子查詢(由裡及外)
SELECT `StudentNo`, `SubjectNo`,`StudentResult`
FROM `result`
WHERE `SubjectNo` = (
SELECT `SubjectNo` FROM `subject`
WHERE `SubjectName` = '高等數學-1'
)
例2: 全部使用子查詢
分數不小於80分的學生的學號和姓名
-- 由裡及外
SELECT `StudentNo`,`StudentName` FROM `student` WHERE `StudentNo` IN (
SELECT `StudentNo` FROM `result` WHERE `StudentResult` >= 80 AND `SubjectNo` = (
SELECT `SubjectNo` FROM `subject` WHERE `SubjectName` = '高等數學-1'
)
)
練習
查詢C語言-1 前五名同學的成績資訊(學號,姓名,分數)
SELECT `student`.`StudentNo`,`StudentName`,`StudentResult`
FROM `student`
LEFT JOIN `result`
ON `student`.`StudentNo` = `result`.`StudentNo`
WHERE `SubjectNo` = (
SELECT `SubjectNo` FROM `subject` WHERE `SubjectName` = 'C語言-1'
)
ORDER BY `StudentResult` DESC
LIMIT 0,5
4.7 分組和過濾
group by 欄位
:根據欄位進行分組
having 條件
:對分組後的欄位進行過濾
-- 查詢不同課程的平均分,最高分,最低分
-- 核心:根據不同課程進行分組
SELECT `SubjectName`,AVG(`StudentResult`) AS 平均分,MAX(`StudentResult`) AS 最高分,MIN(`StudentResult`) AS 最低分
FROM result r
RIGHT JOIN `subject` sub
ON r.`SubjectNo` = sub.`SubjectNo`
GROUP BY r.`SubjectNo` -- 通過什麼欄位分組
HAVING 平均分 >= 80 -- 分組後進行過濾