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
參考連結:
-
SQL的連表查詢 詳細s562872451的部落格-CSDN部落格連表查詢 https://blog.csdn.net/s562872451/article/details/80474726
-
SQL多表連線查詢(詳細例項) - 博雅源 - 部落格園 https://www.cnblogs.com/wgphp/p/8183812.html
輸出結果:輸出右表的所有資訊,左表中沒有匹配的行資訊用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`
輸出結果:
總結:
-
我要查詢哪些資料? select...
-
從哪幾個表查? from 表 join方法 連線的表 on 交叉條件
-
假設存在一種多張表查詢,慢慢來,先查詢兩張表,然後再慢慢增加。
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的
categoryid | categoryname | pid |
---|---|---|
2 | 資訊科技 | 1 |
3 | 軟體開發 | 1 |
5 | 美術設計 | 1 |
-
子類:父類id不是1的,即上面剩下的資料
categoryid | categoryname | pid |
---|---|---|
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考試一科
輸出結果: