SQLyog基本操作(五)-where條件子句、連接查詢、自連接查詢


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種:

img

 -- 練習:查詢參加了考試的同學,輸出學生信息:學號、姓名、科目編號、分數
 -- 查詢所有學生信息
 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的

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考試一科

輸出結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM