查詢數(shù)據(jù)是整個業(yè)務(wù)邏輯中使用的最多也是最復(fù)雜的!
以前的語法:
select *|字段列表from表名where查詢條件
比較完整的語法:
select[select選項]*|字段列表[as字段別名]from數(shù)據(jù)源[where子句][group by子句][having子句][order by子句][limit子句];
注意:
1,from后面的子句往往稱之為:五子查詢,也叫作五子句!
2,五子查詢的選項都可以沒有,但是如果有的話,就必須按順序?qū)懀?/p>
select選項
是指系統(tǒng)在查詢到數(shù)據(jù)之后,如何顯示結(jié)果,有兩個值:
all:也是默認(rèn)值,保留所有的查詢的結(jié)果
distinct:去重,去掉重復(fù)的記錄,這里的重復(fù)是指查詢出來的結(jié)果當(dāng)中,所有的字段都相同(也就是完全一樣)
別名:所謂的別名,就是給字段或其他表達(dá)式等標(biāo)識符起一個名字,基本語法是:
字段|表達(dá)式|表|子查詢結(jié)果 [as]別名
這里的as可以省略,但是為增強(qiáng)可讀性,一般還是寫上!
為什么要有別名?
第一:如果出現(xiàn)多表連接查詢的時候,往往不同的表中會有相同的字段名,如果使用同名字段,PHP就不好區(qū)分!
應(yīng)該給重復(fù)的字段起一個別名:
第二,通常都要給一個表達(dá)式起一個別名,代表該表達(dá)式的含義!
第三,在真實的項目中,表名往往都比較長,懶得寫!
第四,當(dāng)數(shù)據(jù)源是一個子查詢的時候,必須給該子查詢語句起一個別名
先模擬一下:
數(shù)據(jù)源:這里的數(shù)據(jù)源就是指查詢的數(shù)據(jù)的來源,可能是一張表,也可能是多張表,也可能是一個子查詢的結(jié)果,總之是一個結(jié)果集!
比較完整的語法:
select[select選項]*|字段列表[as字段別名]from數(shù)據(jù)源[where子句][group by子句][having子句][order by子句][limit子句];
但是,一條真實的select語句,有可能連字段都可以沒有!
典型的,select語句可以當(dāng)簡單的計算器來使用:
也就是說,MySQL中是sql語句,在執(zhí)行select操作的時候,可以沒有數(shù)據(jù)源!
但是,理論上來說,一條sql語句就必須從一個數(shù)據(jù)源中去獲得數(shù)據(jù)!
所以,為了保證sql語句的結(jié)構(gòu)的完整性,在MySQL中執(zhí)行select語句的時候,如果沒有數(shù)據(jù)源,就使用一個虛擬表!
虛擬表:dual
語法:
where 表達(dá)式
功能:
通過限定條件對數(shù)據(jù)進(jìn)行篩選,得到想要的結(jié)果
流程:
逐一的取出每一條記錄,先通過當(dāng)前記錄來計算where后面表達(dá)式的值,如果計算的結(jié)果為真(非0),就返回該記錄,如果計算的結(jié)果為假(0),就不返回該記錄,相當(dāng)于對所有的記錄做了一次遍歷!
思考:如果執(zhí)行如下的語句,會是什么樣結(jié)果
所以,where子句往往配合著MySQL運(yùn)算符一起使用!
加減乘除、求余
關(guān)系運(yùn)算符:=、!= 或 <>、> 、< 、="">=、<>
注意:這里的等號就是一個等號=
between and:范圍比較,相當(dāng)于閉區(qū)間!比如between A and B,相當(dāng)于數(shù)學(xué)上的[A,B],這里的A不能大于B
in和not in 語法形式:in | not in(集合元素)
作用:判斷某個值是否屬于某個集合當(dāng)!
邏輯運(yùn)算符:&& 或 and、|| 或 or、! 或 not
也稱之為分組統(tǒng)計查詢語句!
語法形式:group by 字段1,[字段2];
所以,分組之后,只會從每個組內(nèi)部取出第一條記錄,這種查詢毫無意義!
因為,分組統(tǒng)計查詢的主要作用不是分組,而是統(tǒng)計!或者說分組的目的就是對每個分組進(jìn)行相關(guān)的統(tǒng)計!
此時,就要用到系統(tǒng)中的一些統(tǒng)計函數(shù):
sum():求和,就是將某個分組內(nèi)個某個字段的值全部相加!
max():求某個組內(nèi)某個字段的最大值
min():求某個組內(nèi)某個字段的最小值
avg():求某個組內(nèi)某個字段的平均值
count():統(tǒng)計某個組內(nèi)非null記錄的個數(shù),通常用count(*)來表示!
在真實的項目中,group by子句往往都是配合著統(tǒng)計函數(shù)來一起使用的:
案例:在php_student表中,以home字段進(jìn)行分組,并求每個分組的個數(shù)、年齡總和、平均分!
當(dāng)然,group by后面還可以有多個字段,稱之為多字段分組查詢!
其實,就是先根據(jù)字段1進(jìn)行分組,然后再根據(jù)字段2進(jìn)行分組(分組的個數(shù)變多了)
一個需要注意的地方:
凡是使用統(tǒng)計函數(shù)的sql語句,系統(tǒng)都會默認(rèn)的進(jìn)行分組,如果沒有g(shù)roup by相當(dāng)于將整個表分成一組,因為統(tǒng)計函數(shù)的對象一定是一個分組
就是在進(jìn)行分組統(tǒng)計的時候,往往需要做上級統(tǒng)計!
比如:先統(tǒng)計各個班的總?cè)藬?shù),然后再計算所有班級的總?cè)藬?shù),就得到了一個年級的總?cè)藬?shù)!
先把每個班的最高分統(tǒng)計一下,然后再把每個班的最高分再取最高分,就得到了一個年級的最高分!
在MySQL中,也支持回溯統(tǒng)計,其實就是在語句的后面加上with rollup
注意:既然group by子句出現(xiàn)在where子句之后,就說明可以先將整個數(shù)據(jù)源進(jìn)行一次篩選,然后再對篩選的記錄進(jìn)行分組統(tǒng)計查詢!
比較完整的語法:
select[select選項]*|字段列表[as字段別名]from數(shù)據(jù)源[where子句][group by子句][having子句][order by子句][limit子句];
having子句和where子句一樣,也是用來篩選數(shù)據(jù)的,通常是對group by之后的統(tǒng)計結(jié)果再次進(jìn)行條件判斷以得到想要的結(jié)果!
如果對上面的數(shù)據(jù)結(jié)果集再次的進(jìn)行一次篩選,比如,只顯示平均分在80分以上的!
那么,having子句和where子句到底有什么區(qū)別呢?
二者的比較:
1,如果語句中只有having子句或者where子句,此時,它們的效果相同!
2,二者最本質(zhì)的區(qū)別是:where子句是把磁盤(外存)上的數(shù)據(jù)篩選到內(nèi)存中,而having子句是把內(nèi)存中的數(shù)據(jù)再次的進(jìn)行篩選!也就是說,執(zhí)行到having子句的時候,數(shù)據(jù)已經(jīng)在內(nèi)存中了!
3,where子句不能使用統(tǒng)計函數(shù)!而having子句可以!因為只有在內(nèi)存中的數(shù)據(jù)才能進(jìn)行統(tǒng)計(數(shù)據(jù)的運(yùn)算)
比較完整的語法:
select[select選項]*|字段列表[as字段別名]from數(shù)據(jù)源[where子句][group by子句][having子句][order by子句][limit子句];
order by:根據(jù)某個字段進(jìn)行排序,有升序和降序!
語法
order by字段名[asc|desc]
默認(rèn)值是升序,也就是asc,當(dāng)然,排序要遵守校對集的規(guī)則!
思考:如果此時有兩個記錄的成績是一樣的,如何排序?
多字段排序:order by字段1[asc|desc],字段2[asc|desc];
規(guī)則:先按字段1進(jìn)行排序,如果字段1相同(無法準(zhǔn)確的確定順序),再按字段2進(jìn)行排序!并且字段1的排序規(guī)則可以和字段2的排序規(guī)則不一樣,比如:字段1按升序排,字段2按降序拍!
聯(lián)系客服