1. 程式人生 > 其它 >MySQL筆記4:DQL 查詢資料

MySQL筆記4:DQL 查詢資料

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

NULLIS 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 -- 分組後進行過濾