1. 程式人生 > 其它 >SQLyog基本操作(五)

SQLyog基本操作(五)

4.2.2 去重 distinct

作用:去除SELECT查詢出來的結果中重複的資料,重複的資料只顯示一條

-- 查詢一下有哪些同學參加了考試
-- 查詢學生的全部考試資訊,顯示result表的所有資料
SELECT * FROM `result`
-- 通過學號查詢哪些同學參加了考試,`StudentNo`表示學號
SELECT `StudentNo` FROM `result`
-- 去除重複的學號資訊,重複的資料(此處指學號資訊)只顯示一條
SELECT DISTINCT `StudentNo` FROM `result`

4.2.3 資料庫的列(表示式)

資料庫中的表示式:包括文字值、列、null、函式、計算表示式、系統變數等。

格式:SELECT 表示式 FROM 表

檢視MySQL技術文件

5.7版本:MySQL :: MySQL 5.7 Reference Manual :: 12.1 Built-In Function and Operator Reference

https://dev.mysql.com/doc/refman/5.7/en/built-in-function-reference.html

8.0版本:MySQL :: MySQL 8.0 Reference Manual :: 12.1 Built-In Function and Operator Reference

https://dev.mysql.com/doc/refman/8.0/en/built-in-function-reference.html

-- 通過函式檢視系統版本
SELECT VERSION(); -- 5.7.19

-- 用數學表示式來計算結果,將結果儲存為“計算結果”
SELECT 100*3-1 AS '計算結果' -- 299

-- 查詢自增的步長(變數)
SELECT @@auto_increment_increment -- 1

-- 對資料進行某種整體運算,例:將學員考試成績+1後輸出
SELECT `StudentNo`,`StudentResult`+1 AS '提分後' FROM `result`

4.3 where條件字句

作用:檢索資料中符合條件的值,搜尋的條件由一個或多個表示式組成,結果是布林值。

常用的邏輯運算子:

建議使用英文字母方式,見名知意!!!

運算子語法描述
and 或 && a and b 或 a&&b 邏輯與,兩個都為真,結果為真
or 或 || a or b 或 a||b 邏輯或,其中一個為真,結果為真
not 或 ! not a 或 !a 邏輯非,非真則假,非假則真
-- 練習
-- 使用and查詢成績在95~100之間的學員
SELECT `StudentNo`,`StudentResult` FROM `result`
WHERE `StudentResult`>=95 AND `StudentResult`<=100

-- 使用&&查詢成績在95~100之間的學員
SELECT `StudentNo`,`StudentResult` FROM `result`
WHERE `StudentResult`>=95 AND `StudentResult`<=100

-- 使用or檢視成績為60或95的學員
SELECT `StudentNo`,`StudentResult` FROM `result`
WHERE `StudentResult`=60 OR `StudentResult`=95

-- 使用||檢視成績為60或95的學員
SELECT `StudentNo`,`StudentResult` FROM `result`
WHERE `StudentResult`=60 || `StudentResult`=95


-- 使用not檢視學號不是10000的學員
SELECT `StudentNo`,`StudentResult` FROM `result`
WHERE NOT `StudentNo`=10000

-- 使用!檢視學號不是10000的學員
SELECT `StudentNo`,`StudentResult` FROM `result`
WHERE `StudentNo`!=10000

-- 使用between... and...檢視成績在90~100之間的學員
SELECT `StudentNo`,`StudentResult` FROM `result`
WHERE `StudentResult` BETWEEN 90 AND 100
  • 模糊查詢:比較運算子

運算子語法描述
IS NULL a IS NULL 如果操作符為NULL,結果為真
IS NOT NULL a IS NOT NULL 如果操作符不為NULL,結果為真
BETWEEN... AND ... a BETWEEN b AND c 如果a在b和c之間,結果為真
LIKE a LIKE b SQL匹配,如果a匹配b,結果為真
IN a IN(a1,a2,a3,...) 如果a為a1,a2...其中的某一個,結果為真
  • LIKE練習:模糊查詢

-- LIKE練習:%代表0~任意多個字元 _代表1個字元
-- 查詢姓李的同學:第一個字元為劉,後面的字元任意
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:條件為具體的一個或多個值,並非模糊匹配,而是具體匹配
-- 查詢10000、10001、10002號學員
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `StudentNo` IN(10000,10001,10002)

-- 查詢在地址不詳的學員
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `Address` IN('地址不詳');

-- 查詢在地址不詳和北京市東城區的學員
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `Address` IN('地址不詳','北京市東城區');
  • NULL、NOT NULL練習:

-- 查詢地址為空的學生
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `Address`='' OR `Address` IS NULL

-- 查詢出生日期不為空的同學
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `BornDate` IS NOT NULL

4.4 聯表查詢 join

我們在做查詢的時候,會遇到可能一張表滿足不了我們要求的情況,可能要求獲取的資料來自於兩張、三張甚至更多張表,對此,我們就應該使用聯表查詢。

  • 3種JOIN對比:

  • 實際JOIN理論細分可分為7種:

-- 練習:查詢參加了考試的同學,輸出學生資訊:學號、姓名、科目編號、分數
-- 查詢所有學生資訊
SELECT * FROM `student`
-- 查詢所有成績資訊
SELECT * FROM `result`
/*
根據上面兩條語句查詢出來的效果,我們還需要一個一個對照著學生的學號去找,這種方式過於麻煩,因此我們需要用一種方式將這些資料拼接起來,方便我們檢視。

思路:
1.分析需求:分析查詢的欄位來自那些表?student、result
2.連線方式:確定使用哪種連線連線查詢?7種
確定交叉點:這兩個表中哪個資料是相同的
*/
-- join on 連線查詢(判斷的條件)
-- where 等值查詢
-- 分析兩張表結構,我們可以判斷的條件為:student表中的`StudentNo`=result表中的`StudentNo`
-- 1.使用INNER JOIN:內連線,也稱為自然連線
-- 注意: 內連線是從結果中刪除其他被連線表中沒有匹配行的所有行,所以內連線可能會丟失資訊。
-- 重點:內連線,只查匹配行。
-- 語法:INNER可省略,單獨寫JOIN時,預設INNER JOIN
SELECT s.`StudentNo`,`StudentName`,`SubjectNo`,`StudentResult`
FROM `student` AS `s`
INNER JOIN `result` AS `r`
WHERE s.`StudentNo`=r.`StudentNo`

輸出結果:保留兩個表中都有匹配的行

-- 外連線:與內連線相比,即使沒有匹配行,也會返回一個表的全集。
-- 外連線分為三種:左外連線,右外連線,全外連線,對應SQL:LEFT/RIGHT/FULL OUTER JOIN。
-- 通常我們省略outer 這個關鍵字,寫成:LEFT/RIGHT/FULL JOIN。
-- 重點:至少有一方保留全集,沒有匹配行用NULL代替。
-- 1.LEFT OUTER JOIN,簡稱LEFT JOIN,左外連線(左連線)
-- 結果集保留左表的所有行,但只包含第二個表與第一表匹配的行,第二個表相應的空行被放入NULL值。
-- 通過結果,可以看到左連線包含了第一張表的所有資訊,在第二張表中如果沒有匹配項,則用NULL代替
-- 2.RIGHT OUTER JOIN,簡稱RIGHT JOIN,右外連線(右連線)
-- 右外連線保留了第二個表的所有行,但只包含第一個表與第二個表匹配的行,第一個表相應空行被入NULL值。
-- 通過結果,可以看到右連線包含了第二張表的所有資訊,在第一張表中如果沒有匹配項,則用NULL代替
-- 3.FULL OUTER JOIN,簡稱FULL JOIN,,全外連線(全連線)
-- 全外連線,簡稱:全連線,會把兩個表所有的行都顯示在結果表中
-- 包含了兩張表的所有記錄,沒有記錄丟失,沒有匹配的行用NULL代替。
--
-- 2.使用RIGHT JOIN 側重於result
SELECT * FROM `student`
SELECT * FROM `result`
SELECT s.`StudentNo`,`StudentName`,`SubjectNo`,`StudentResult`
FROM `student` AS `s`
RIGHT JOIN `result` AS `r`
ON s.`StudentNo`=r.`StudentNo` -- 此處使用ON

參考連結

輸出結果:輸出右表的所有資訊,左表中沒有匹配的行資訊用NULL填充

-- 3.使用LEFT JOIN    側重於student
SELECT * FROM `student`
SELECT * FROM `result`
SELECT s.`StudentNo`,`StudentName`,`SubjectNo`,`StudentResult`
FROM `student` AS `s`
LEFT JOIN `result` AS `r`
ON s.`StudentNo`=r.`StudentNo` -- 此處使用ON

輸出結果:輸出左表的所有資訊,右表中沒有匹配的行資訊用NULL填充

JOIN ON 連線查詢 --- ON在連線查詢中均適用

WHERE 等值查詢 --- 在INNER JOIN可以使用

  • INNER JOIN、LEFT JOIN、RIGHT JOIN結果對比:

操作描述
INNER JOIN 如果表中至少有一個匹配,就返回;如果兩張表都有,就確定是哪張表即可
LEFT JOIN 會從左表中返回所有的值,即使右表中沒有匹配
RIGHT JOIN 會從右表中返回所有的值,即使左表中沒有匹配
-- 查詢缺考的同學:側重於找出成績為NULL的同學,故使用LEFT JOIN
SELECT s.`StudentNo`,`StudentName`,`SubjectNo`,`StudentResult`
FROM `student` `s`
LEFT JOIN `result` `r`
ON s.`StudentNo`=r.`StudentNo`
WHERE `StudentResult` IS NULL

-- 思考題:查詢參加考試的同學資訊:學號、學生姓名、科目名稱、分數
/*
思路:
1.分析需求,分析查詢的欄位來自哪些表?student、result、subject
2.確定使用哪種連線查詢?7種
確定交叉點:這兩個表中哪個資料是相同的
判斷的條件:`student`表中的`StudentNo`=`result`表中的`StudentNo`
`result`表中的`SubjectNo`=`subject`表中的`SubjectNo`
*/
-- 先連線查詢student表、result表,用StudentNo進行連線
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `student` s
RIGHT JOIN `result` r -- 側重於參加考試同學的成績分數,故使用RIGHT JOIN
ON s.`StudentNo`=r.`StudentNo`
-- 再連線查詢result表、subject表,用SubjectNo進行連線
INNER JOIN `subject` sub
ON r.`SubjectNo`=sub.`SubjectNo`

-- 或
-- 先連線查詢student表、result表,用StudentNo進行連線
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `student` s
RIGHT JOIN `result` r -- 側重於參加考試同學的成績分數,故使用RIGHT JOIN
ON s.`StudentNo`=r.`StudentNo`
-- 再連線查詢result表、subject表,用SubjectNo進行連線
LEFT JOIN `subject` sub
ON r.`SubjectNo`=sub.`SubjectNo`

輸出結果

總結:

  1. 我要查詢哪些資料? select...

  2. 從哪幾個表查? from 表 join方法 連線的表 on 交叉條件

  3. 假設存在一種多張表查詢,慢慢來,先查詢兩張表,然後再慢慢增加。

4.5 自連線查詢

定義:自己的表和自己的表連線,核心:一張表拆為兩張一樣的表即可。

在school資料庫中新增catalog表

-- 建立category表:categoryid為子類id,pid為父類id
DROP TABLE IF EXISTS `category`;
CREATE TABLE IF NOT EXISTS `category`(
`categoryid` INT(3) NOT NULL COMMENT '子類id',
`pid` INT(3) NOT NULL COMMENT '父類id,如果沒有父類id,則為1',
`categoryname` VARCHAR(10) NOT NULL COMMENT '種類名字',
PRIMARY KEY (`categoryid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

-- 插入category資料
INSERT INTO `category` (`categoryid`,`pid`,`categoryname`)
VALUES (2,1,'資訊科技'),
(3,1,'軟體開發'),
(5,1,'美術設計'),
(4,3,'資料庫'),
(8,2,'辦公資訊'),
(6,3,'web開發'),
(7,5,'ps技術');

輸出結果

我們分析這張表,可以看出,在這張表內實現了分級,例如:資訊科技子類id=2,父類id=1,而資料庫子類id=4,父類id=1。我們可以根據上述規則將這張表拆分為兩個表:

  • 父類:父類id都是1的

categoryidcategorynamepid
2 資訊科技 1
3 軟體開發 1
5 美術設計 1
  • 子類:父類id不是1的,即上面剩下的資料

categoryidcategorynamepid
4 資料庫 3
6 web開發 3
7 ps技術 5
8 辦公資訊 2

操作:查詢父類對應的子類關係

父類子類
資訊科技 辦公資訊
軟體開發 資料庫
軟體開發 web開發
美術設計 ps技術
-- 對於都在一個表中的欄位,我們就使用自連線查詢
-- 查詢父子資訊:把一張表拆為兩個一模一樣的表
-- 拆名字
SELECT a.`categoryname` AS 父欄目 ,b.`categoryname` AS 子欄目
-- 拆表
FROM `category` AS a,`category` AS b
-- 通過id進行連線
WHERE a.`categoryid`=b.`pid` -- 此處不能調換位置,要一一對應

輸出結果

-- 通過自連線查詢實現
SELECT a.`categoryname` 科目類別,b.`categoryname` 課程
FROM `category` a
INNER JOIN `category` b -- 此處只能用INNER JOIN
ON a.`categoryid`=b.`pid` -- 此處不能調換位置,要一一對應

輸出結果

-- 補充練習:
-- 1.查詢學員所屬的年級,輸出學員的資訊:學號、學生姓名、年級名稱
SELECT `StudentNo`,`StudentName`,`gradeName`
FROM `student` s
INNER JOIN `grade` g
ON s.`GradeID`=g.`gradeID`

-- 與上面結果相同,只是順序有交換
SELECT `StudentNo`,`StudentName`,`gradeName`
FROM `student` s
LEFT JOIN `grade` g
ON s.`GradeID`=g.`gradeID`

輸出結果:

-- 2.查詢科目所屬年級,輸出科目名稱、年級名稱
SELECT `SubjectName`,`gradeName`
FROM `subject` s
INNER JOIN `grade` g
ON s.`GradeID`=g.`gradeID`

-- 與上面結果相同,只是順序有交換
SELECT `SubjectName`,`gradeName`
FROM `subject` s
LEFT JOIN `grade` g
ON s.`GradeID`=g.`gradeID`

輸出結果:

-- 3.查詢參加資料庫結構-1考試的同學資訊:學號、學生姓名、科目名稱、分數
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult`
FROM `student` s
INNER JOIN `result` r
ON s.`StudentNo`=r.`StudentNo`
RIGHT JOIN `subject` sub -- 側重於所有科目
ON r.`SubjectNo`=sub.`SubjectNo`
WHERE `SubjectName`='資料庫結構-1' -- 單獨選出資料庫結構-1考試一科

輸出結果: