【D1n910】(19/42) C++語言程序設(shè)計(jì) - MySQL數(shù)據(jù)庫學(xué)習(xí)筆記 2.4 排序、分組
正常操作,正常分析,大家好,我是D1N910,這是我觀看【MySQL數(shù)據(jù)庫】C++語言程序設(shè)計(jì) - MySQL數(shù)據(jù)庫:

從而整理的學(xué)習(xí)筆記。我會繼續(xù)努力的。
如果你沒看過之前的專欄內(nèi)容,那么強(qiáng)烈建議一定要先看看再繼續(xù)往下看!






Unit09 where子句
where子句的語法
使用比較運(yùn)算符
使用SQL提供的運(yùn)算符
使用邏輯運(yùn)算符
1. where子句的語法
作用
》根據(jù)條件表達(dá)式從數(shù)據(jù)源中篩選符合條件的記錄
語法
》select 字段列表
????from 數(shù)據(jù)源
????????where 條件表達(dá)式
2.使用比較運(yùn)算符
比較運(yùn)算符
> < >= <= = !=(<>)
示例
》列出考試及格的信息
????select * from choose where score>=60;
列出'張三”的考試成績的信息
運(yùn)行結(jié)果
3.使用SQL提供的運(yùn)算符
between...and
判斷表達(dá)式的值是否在給定的閉區(qū)間
語法
>表達(dá)式 between 值1 and 值2
示例
>列出成績在70~90之間的信息,等效于 >= 70 and <=90, 閉區(qū)間[70, 90]
運(yùn)行結(jié)果
e.g. 列出選課時間是2018年的信息
運(yùn)行結(jié)果
3.2.is null
判斷表達(dá)式的值是否為null
語法
????>表達(dá)式 is null
示例
??? >列出沒有班級的學(xué)生的信息
????>列出沒有學(xué)生的班級的信息,利用左外連接
可以看到添加了? where s.student_no is null?的是只剩下 student_no is null 的。這個也是檢索表中為空的數(shù)據(jù)的辦法。
為什么要用 is null 呢?為什么不能夠直接用null判斷呢?
觀察上面的代碼,可以知道,sql 中 null 并不能夠直接來進(jìn)行符號表達(dá)式的比對。結(jié)果都是 NULL!
那為什么 NULL 值要用 IS 關(guān)鍵字呢?為什么要以這種方式來處理 NULL?
因?yàn)?,?SQL 中,NULL 表示“未知”。也就是說,NULL 值表示的是“未知”的值。
NULL = 未知;
在大多數(shù)數(shù)據(jù)庫中,NULl 和空字符串是有區(qū)別的。
但并不是所有數(shù)據(jù)庫都這樣,例如,Oracle 就不支持空字符串,它會把空字符串自動轉(zhuǎn)成 NULL 值。
在其他大多數(shù)數(shù)據(jù)庫里,NULL 值和字符串的處理方式是不一樣的:
空字符("")串雖然表示“沒有值”,但這個值是已知的。
NULL 表示 “未知值”,這個值是未知的。
來源https://www.yii666.com/blog/24808.html
當(dāng)然,如果是想要找到不為空的,也很簡單,加個 not 就行
3.3.in
判斷表達(dá)式的值是否位于一個列表中,有點(diǎn)“或”的意思。
語法
????>表達(dá)式 in(值1,值2, ...)
示例
????>列出選修了 'C語言' 和 'Java語言’ 的信息,包括學(xué)號、課程名稱和成績
3.3、like
判斷表達(dá)式的值是否符合給定的模式
語法
????》 表達(dá)式 like?'模式'
通配符
????》%:匹配任意長度的任意字符
????》_:匹配一位任意字符
示例
》列出學(xué)生表中姓 '張' 的學(xué)生的信息
這里感覺有點(diǎn)正則表達(dá)式的意思了??
模式中包含通配符
> 示例:列出 information_schema 表中,表名以'user_’開頭的表的信息
1. 使用\作為轉(zhuǎn)義字符
2. 自定義轉(zhuǎn)義字符
下面這種更加通用,因?yàn)樯厦娴霓D(zhuǎn)義字符可能是MySQL專用的,下面這種則很多數(shù)據(jù)庫軟件都支持。
escape
v.逃跑;(從監(jiān)禁或管制中)逃走;逃出;(從不愉快或危險(xiǎn)處境中)逃脫;擺脫;逃避;避免(不愉快或危險(xiǎn)的事物);逃脫,幸免于難;被忘掉;漏出;(不自覺地)由…發(fā)出
n.逃脫;逃避;逃避現(xiàn)實(shí);解脫;消遣;漏出;滲出(量);Esc鍵
-- 來自百度翻譯
4.使用邏輯運(yùn)算符
用以解決多個條件的問題
4.1、與運(yùn)算 and
語法
示例1
????列出成績在70~90之間的信息
列出'張三’的成績信息
運(yùn)行結(jié)果
示例2
????使用where子句實(shí)現(xiàn)三表內(nèi)連接
>語法
示例
檢索學(xué)生的考試成績信息,列出學(xué)號、姓名、選修課程名稱和成績,之前都要 join?in
4.2、或運(yùn)算 or
語法
????邏輯表達(dá)式1 or 邏輯表達(dá)式2
示例
任務(wù):列出選修了’C語言’和’Java語言’的信息,包括學(xué)號、課程名稱和成績
這里可以看到用括號吧 or 的包裹起來了
4.3 非運(yùn)算 not(!)
語法
>not 邏輯表達(dá)式 或者?。ㄟ壿嫳磉_(dá)式)
示例
任務(wù)列出選修人數(shù)上限不是60的課程的信息
非在MySQl有兩種方式,一種是 !,一種是 not
運(yùn)算符取反

示例
列出有班級的學(xué)生的信息
先看?student 表信息
測試 in、not in
如此正常
但是上面的不能和下面一樣把?class_no 為 3 的輸出
原理
class_no in(1,2,null) ==>? class_no=1 or class_no=2 or class_no=null
==> class_no=1 or class_no=2
因?yàn)檫@里是or,所以??class_no=null 可以忽略掉
class_no not in(1,2,null) ==>??class_no !=1 and?class_no!=2 and?class_no!=null
因?yàn)槭莂nd,而 class_no!=null 也比較不了,所以查出來的都是永不為真的, 得到結(jié)果都是不符合條件的。
Unit10 排序&分組
排序
組函數(shù)
分組
01、排序
》order by子句
作用
>按照給定的字段或字段列表對結(jié)果集進(jìn)行排序。其中asc從上到下,從小到大;desc從上到下,從大到小。NULL 視為最小值。
語法
其中,
????asc: 表示升序排序 缺省方式
????desc: 表示降序排序
1、單列排序
結(jié)果如下
利用我們之前的exam表,還可以模擬下自己創(chuàng)建數(shù)據(jù)列的情況
2、多列排序
正常按照升序排序


02、組函數(shù)
組函數(shù)其實(shí)有點(diǎn)像是庫函數(shù)
常用的組函數(shù)
count(expr) 返回 expr 的非空值的數(shù)量
max(expr) 返回 expr 的最大值
min(expr) 返回 expr 的最小值
sum(expr) 返回 expr 的累加和
avg(expr) 返回 expr 的平均值
組函數(shù)有點(diǎn)像excel的函數(shù)
e.g.
得到 choose 中的非空值數(shù)量
查看choose_time的最大最小值(這里是時間,所以是最早最晚)
查看student_no為2018001的成績的總分和平均分
組函數(shù)對null值的處理一忽略
e.g. A
可以看到結(jié)果里,對于 count 全部的,展示的是 8,但是 count score的,展示的是6.
原因就是因?yàn)椴豢紤] null
e.g. B
組函數(shù)的參數(shù)可以使用 distinct 修飾
distinct 之前學(xué)過,作用是忽略 null!
??
03.分組
前面我們學(xué)的是查所有人的平均分,現(xiàn)在我們想查每個人的平均分應(yīng)該如何實(shí)現(xiàn)呢?
group by子句
group by子句將查詢結(jié)果按照某個字段(或多個字段)進(jìn)行分組(字段值相同的
記錄作為一個分組),通常與聚合函數(shù)一起使用
語法
示例
>統(tǒng)計(jì)每一個學(xué)生的平均分
結(jié)果:
統(tǒng)計(jì)每個數(shù)據(jù)庫表的數(shù)量
結(jié)果:
統(tǒng)計(jì)學(xué)生總分和平均分
錯誤提示
分組所能出現(xiàn)的字段
(1)分組字段,即跟隨在 group by 之后的字段
(2)組合函數(shù)字段,比如sum(組合函數(shù)字段)
下面的例子可以展現(xiàn)出(1)、(2)
添加了 course_no 到 group by 之后:
(3)依賴于分組字段的字段
先看下面的 student 表的內(nèi)容
成功
這里主要是因?yàn)榉纸M的字段學(xué)號對應(yīng)的班級號字段只有一個,所以成功了。
如果分組的時候反過來,按照班級分組,然后展示對應(yīng)的學(xué)號,那么又會報(bào)錯。
原因是因?yàn)榘凑瞻嗉壏纸M的時候,因?yàn)?s 表中的 class_no 不唯一,所以報(bào)錯了。
上面是單列分組,下面示范多列分組。
可以看出,分組字段越多,分組也就越多。
現(xiàn)在考慮如何在篩選分組的時候類似 where 再做一層篩選,
比如篩選?information_schema.tables中 cnt 大于50的;
先嘗試一下使用?where ,發(fā)現(xiàn)失敗了。
1、where cnt>50 # where子句中不能使用字段或表達(dá)式的別名
原因:因?yàn)?where 語句雖然放在了別名語句之后,但是在執(zhí)行上 where 會比 別名 早,相當(dāng)于 where 執(zhí)行的時候,別名 還沒取呢!
2、?where count(*)>50 # where子句中不能使用組函數(shù)
為了破解上面的問題,我們摸出平替??
having子句
可以對分組子句進(jìn)行篩選
語法
????having 條件表達(dá)式
示例
????> 列出平均分及格的學(xué)生的信息
下面是結(jié)果
????> 列出表的數(shù)量多于50的數(shù)據(jù)庫的信息
除了可以用別名,用 count(*) 也是可以的
下面我們也來看看語法順序和執(zhí)行順序
語法順序
select
????from
????????where
????????????group by
????????????????having
????????????????????order by
單條語句執(zhí)行順序
from(要找到表,所以 from 先執(zhí)行。因?yàn)楸砻麆e名后,整個語句只能用別名,不能用字段的別名)
????where(要篩選,用不了字段的別名,所以 where 在 select 前?第二位)
????????select
????(下面的語句都可以用別名,說明他們都在 select 之后)
????????????group by
????????????????having(它是對分組結(jié)果進(jìn)行篩選,所以一定是在 group by 后邊)
????????????????????order by(它是對最終結(jié)果進(jìn)行排序,所以一定是在最后面)

恭喜我們,掌握了數(shù)據(jù)庫表的排序、分組
我們的學(xué)習(xí)進(jìn)度為 19/42!
未完待續(xù)!