高級數據操作
having子句:having子句也是用來判斷條件,與where子句基本一致。
區別
1.where是對數據源的數據進行操作
2.having是對臨時數據(where操作完,group by操作之後)進行操作
對別名的使用:只有having能夠使用,而where只能操作數據源中的原始字段
對合計函數的使用:只有having可以,having出現在group by之後,而where在group by之前
使用字段別名
order by子句:排序,對字段進行排序,使用校對集進行比較
語法:order by 字段 [排序方式],字段 [排序方式],… 默認的是升序排序
多字段排序
limit子句:限制獲取的條數
限制獲取數據的位置和數目
語法:limit offset,number
offset:起始位置,偏移量
number:限制的獲取記錄的數量
簡單使用
複合使用
limit通常用於數據獲取的數量控制以及位置控制。
limit用於分頁。
聯合查詢
將表與表之間(或者表內不同的記錄)進行縱向的合併
為什麼要使用聯合查詢?
當大數據量存在的時候,一張表往往不夠存儲。
語法:select語句 union[union選項] select 語句
注意
1.union的使用,要滿足兩個select語句得到的字段數必須一樣
2.union的使用,字段類型可以對應不上,所以數據顯示的時候也會對應不上
原因:union是對兩個select語句的結果進行合併,結果是臨時數據(全部都是字符數據,沒有數據類型),合併後的結果沒有數據類型的概念,全部都是字符串數據。
union選項:與select選項一致,有all和distinct(默認),不管是all還是distinct都是對union之後的最終結果進行操作。
在union(聯合查詢中)如果需要使用order by對語句進行排序,必須使用括號將select語句進行括起來。
(select 語句 order by子句 )
union
(select 語句 order by子句 )
語法正常,卻沒有實現排序
如果在聯合查詢中想正常使用order by記性排序,必須配合使用limit,但是因為limit使用前不知道表中有多少記錄,所以一般limit 後面跟最大值 999999
聯合查詢不僅限於同一張表,多表之間也可以聯合,只要保證字段數量一致即可。
連接查詢join
將多個表對應的數據進行拼接(在字段上橫向進行拼接)。
因為表的存在不是獨立的。通過外鍵進行連接操作。
連接查詢:內連接,外連接,自然連接,交叉連接
內連接
記錄在兩張表都存在,才能夠連接成功。
語法:[inner] join
左表 inner join 右表 on 條件
在join關鍵字左邊的表稱之為左表
在join關鍵字右邊的表稱之為右表
沒有連接條件的內連接是一個笛卡爾積(交叉連接)
正確的內連接
內連接原理
正確的內連接語法
內連接的使用?
要求兩張表組合出數據,要求數據必須要完整的情況下使用內連接。
外連接
跟內連接相似,外連接會將一張表中數據在另外一張表不存在時的記錄也給保存下來。
語法:outer join
外連接分為兩種:左外連接,右外連接,沒有直接的外連接
左外連接:left [outer] join
右外連接:right [outer] join
左外與右外的唯一區別是:以誰為主表,左外連接以左表為主,右外連接以右表為主,但是數據的顯示順序,只跟左右表有關係,跟誰是主表沒有任何關係。
外連接原理
什麼時候使用外連接?
想要知道某個表的全部數據,同時還要將對應其他表的數據給顯示出來,如果不存在則提示沒有。
左右外連接的區別
左右區分
交叉連接
沒有條件的連接,生成一個笛卡爾積
語法:左表 cross join 右表
自然連接
自然連接其實就是自動連接,不需要指定連接條件的連接。
語法:左表 natural [left/right/inner]join 右表
如果想使用自然內連接,那麼不能使用關鍵字inner
正確使用:不使用inner
1.自然連接是自動判斷條件,自動尋找兩張表裡名字相同的字段作為連接條件
2.自然連接在連接之後,會將相同的字段進行合併。
自然外連接:左和右
語法:左表 natural left join 右表
語法:左表 natural right join 右表
注意:自然連接是主動判斷兩張表是否有同名字段,如果有多個同名字段,就會將多個字段組合起來進行比較。
如何使用內連接和外連接來模擬自然內外連接?
語法:using (字段名) 該字段名指的是在兩張表名字相同的字段名
1.到連接的兩張表找對應的字段
2.將第二張表的同名字段給隱藏了(合併)
證明自然連接是會用多個同名字段做連接條件
報表的時候特別多的應用了連接查詢。
子查詢
如果一條查詢語句中包含另外一條查詢語句,那麼該被包含的查詢語句就稱之為子查詢。
子查詢根據在一條查詢語句中出現的位置分為三種
from子查詢
where子查詢
exists子查詢
子查詢根據查詢返回的結果分為四類:
標量子查詢:子查詢的結果是一個具體的值(字段的值)
列子查詢:子查詢的結果得到是某個字段全部或者部分值
行子查詢:返回的結果是一張表,一般有多個字段,不管記錄數多少,記錄數>+1
表子查詢:返回的結果是一張表,一般有多個字段,不管記錄數多少,記錄數>+1
表子查詢和行子查詢的區別:是兩個子查詢出現的位置不一樣,表子查詢出現在from後面,行子查詢出現在where後面。
標量子查詢
獲取PHP1405班的所有學生
1.找到班級ID,select id from pro_class where name = ‘PHP1405’;
2.通過班級ID找學生,select * from pro_student where c_id = ‘’;
標量子查詢
列子查詢
獲取所有有班級的學生(假設學生表與班級表沒有外鍵約束)
有外鍵約束:select * from pro_student where c_id is not null
1.找出當前存在的班級,select id from pro_class where 1
2.找出在當前查詢出來的班級ID裡存在的所有學生
列子查詢
any,some和all的使用
any:任意一個
some:任意一些
all:全部
正向使用,都採用肯定形勢
負向使用,都採用否定形勢
行子查詢
找出班上年齡最大,且身高最高的同學
select * from pro_student order by age desc,height desc limit 1;
缺點是不能保證找出所有的滿足條件的信息。
1.找出班級裡最大的年齡和最高的身高:select max(age),max(height) from pro_student;
2.匹配學生的年齡和身高信息。只能通過行子查詢
行子查詢:通過構建行來進行行比較,如果子查詢返回的結果是2個字段,那麼就需要構建一個2個字段的行,使用()構建
語法:(字段1,字段2,…) = (行:子查詢返回)
表子查詢
要獲取每個班的年齡最小的一個同學
1.如何獲得每個班的第一個學生,使用按照班級分組
2.要在第一步分組之前,先將學生按照年齡升序排序
表子查詢
exists子查詢
判斷子查詢的結果是否為真
視圖
視圖就是一張虛擬表
視圖是有結構但是沒數據的表。
語法
create View 視圖名字 as select語句
視圖本身沒有數據,數據的來源全依賴於select語句從各個數據表中獲取。
上述語句執行之後發生了什麼?
1.產生了一個結構文件
2.產生表
3.會在視圖表中產生一條記錄,在information_schema庫裡的VIEWS表裡。
mysql的語句結束符以及含義
默認是分號:“;”一條語句結束
\g:與分號作用一致
\G:將結果記錄按照一個字段一行顯示
視圖是為了查詢數據
如何查看視圖?語法:select * from 視圖名字,與操作表一樣
調用視圖的原理:select * from student_class_v
1.找到視圖定義的語句
2.找出其中的SQL查詢語句
3.使用SQL語句進行查詢操作
注意:視圖的每次調用,都是去執行對應的SQL語句得到結果。
視圖的維護
修改視圖
語法:alter View 視圖名字 as select語句
刪除視圖
語法:drop View 視圖名字
以上語句做了哪些操作?
1.刪除表(視圖名)
2.刪除視圖結構文件
3.刪除Views表裡的記錄
刪除視圖,並不會對原來的表有任何影響。
視圖的數據操作
可以對視圖的數據進行更新或者插入
對單表視圖進行更新操作
對多表視圖進行更新操作
對單表視圖插入數據:視圖的字段要麼與原表字段一樣,要麼視圖的字段之前的其他字段在對應的表的設計過程中有默認值或者可以為空。
對多表視圖插入數據:不可以
視圖的使用
1.可以節省SQL語句的工作量,不用每次都寫複雜的SQL語句
2.數據安全性,可以將不想給外部看到的表字段給隱藏
3.友好性,用戶感覺都在操作一張獨立的表
以後可以方便的對視圖進行權限控制。
視圖算法
視圖算法指的一個視圖在於外部SQL語句組合使用的時候,服務器來處理整個SQL語句的過程中所使用的算法。
視圖算法有三種:merge,temptable,undefined
merge:將外部SQL語句與視圖的SQL語句進行合併之後,在執行
temptable:先執行視圖的SQL語句得到一個臨時表,外部SQL語句對該臨時表進行操作
undefined:未定義,系統不知道使用哪種,系統會自動去判斷使用哪種,這是系統默認的視圖算法,通常基於效率考慮,會更多的使用merge來處理。
因為以上語句使用了merge算法,導致order by子句被放到了group by子句之後,從而導致數據錯亂。
在定義視圖的時候,指定算法為temptable。
語法:create view algorithm = temptable 視圖名 as select
視圖算法對比(merge和temptable)