子查詢
一條查詢語句出現在另外一條查詢語句的內部,這條語句就被稱之為子查詢語句。
子查詢分類
子查詢可以根據子查詢返回的結果以及子查詢出現的位置兩種方式進行分類
按結果分類:
標量子查詢:子查詢返回的結果是一行一列,一個字段的某一個值
列子查詢:子查詢返回的結果是一列,多行,一個字段有多個值
行子查詢:子查詢返回的結果是一行多列,多行多列
表子查詢:子查詢返回的結果多行多列
按照位置分類:
where子查詢:子查詢出現在where條件之后
from子查詢:子查詢出現在from之后
exists子查詢:出現在exists之后,exists出現在where之后
標量子查詢
子查詢返回的結果是一個標量
列子查詢
子查詢返回的結果是一列。
需求:獲取所有班級的所有學生,學生必須在班級中存在。
select * from student where c_id is not null; -- 無法解決
解決方案
1. 獲取所有的現有班級的id:select id from class;
2. 從學生表中查出所有數據,判斷學生的班級id是否在剛查出來的班級id中存在
集合判斷條件(理解性知識)
集合(1,2,3,4,5)
any:任意一個,1 = any(集合),只要結果在集合中出現過,就返回true
all:全部,必須滿足全部條件才返回真
some:等于其中的一部分,與any完全一致
行子查詢
子查詢返回的結果是一行多列
需求:找出所有班級中年齡最大,同時身高最高的學生;
行子查詢必須構建行元素:有多個字段的元素
select * from 表名 where (字段1,字段2…) =/in (select 字段1,字段2… from 表名);
表子查詢
表子查詢從返回結果的層面上講與行子查詢完全一樣。因為其出現的位置不是在where之后,而是在where之前,from之后。from后接數據源。
需求:求出每個班中身高最高的1個學生。
表子查詢出現的原因:因為某些時候,希望order by在group by之前先執行。
先排序,再分組
視圖
視圖:視圖是一張虛擬表,存在表結構,但是沒有數據。
視圖關鍵字:view
創建視圖
語法:
create view 視圖名字 as select語句;
視圖創建之后發生了什么?
1. 創建視圖結構(虛擬表)
2. 在數據庫對應的文件夾下創建結構文件
視圖是虛擬表,只有結構,沒有數據。
視圖查看
1. 視圖可以像表一樣的查看
show tables/show create table/desc 視圖名
2. 可以通過視圖查看創建語句的方法
show create view 視圖名;
3. 查看視圖數據:與查看表完全一致
視圖不保存數據:數據的來源指的是當視圖被調用的時候,系統會自動調用視圖的創建語句中的select語句去執行。
修改視圖
視圖修改的本質是修改視圖的數據來源。
語法
alter view 視圖名字 as select語句;
刪除視圖
語法
drop view 視圖名字;
視圖作用
1. 節省查詢語句的長度
2. 對外提供訪問接口
保證數據表(基表)的數據安全性。
視圖能夠選擇性的從基表獲取數據,并提供給外部。
3. 對外友好性
視圖能夠對外提供不同的數據信息。(不同的接口定義不同的視圖)
視圖數據增刪改
視圖可以為基表進行數據的增刪改操作,必須滿足以下條件
視圖新增數據
1. 視圖的數據來源(基表)只能有一個
多表視圖不能插入數據
2. 視圖中的所有字段,必須包含了基表中不為空或者沒有默認值的全部字段。
更新數據:基本沒有限制
單表視圖更新
多表視圖更新
刪除數據:與插入數據條件一致,只有單表視圖可以刪除,多表不能刪除
單表視圖刪除
多表視圖刪除
視圖算法
視圖在執行的過程中(視圖被查詢),到底是如何去執行視圖對應的查詢語句。
視圖算法分為三種:
合并:merged,先將視圖的SQL查詢與與外部的查詢語句進行語法合并
臨時表:temptable,先執行視圖里面的查詢語句,結果變成一個臨時表
未定義:undefined,系統自己判斷到底使用合并還是臨時表,默認的
算法指定語法
create view algorithm = 算法 視圖名字 as select語句