(1)具體用法模板:數據庫
CASE expressionexpress
WHEN value1 THEN returnvalue1函數
WHEN value2 THEN returnvalue2大數據
WHEN value3 THEN returnvalue3網站
ELSE defaultreturnvaluespa
END 3d
(2)具體使用示例:code
假設咱們有一個論壇網站,其中有一張User表{ UId,Name,Level },Level是一個int類型,表明了用戶等級類型,例如:1表明骨灰,2表明大蝦等;咱們就能夠用CASE來對其進行等值判斷了:blog
select Name,Rank=( case Level when 1 then '骨灰' when 2 then '大蝦' when 3 then '菜鳥' end ) from User
(1)具體用法模板:排序
CASE
WHEN condition1 THEN returnvalue1
WHEN condition2 THEN returnvalue2
WHEN condition3 THEN returnvalue3
ELSE defaultreturnvalue
END
注意:then後面返回的數據類型要一致, returnvalue一、 returnvalue二、 returnvalue3的數據類型必須一致。
(2)具體使用示例:
假設咱們有一張Score成績表,裏面記錄有全部同窗的成績,此時咱們想要對全部成績進行一個評級,好比成績若是>=90那麼則評爲A級,>=80且<90則評爲B級,這裏咱們怎來寫呢?
select studentId,rank=( case when english between 90 and 100 then 'A' when english between 80 and 89 then 'B' when english between 70 and 79 then 'C' when english between 60 and 69 then 'D' when english < 60 then 'E' else '缺考' end ) from Score
就像使用普通的表同樣,被看成結果集的查詢語句被稱爲子查詢。全部可使用表的地方几乎均可以使用子查詢來代替。例如:咱們若是要找到全部計科一班的同窗信息,能夠首先經過T_Class表找到計科一班的Id,而後再在T_Student表中找到全部ClassId爲計科一班Id的行便可。
select * from T_Student where ClassId= ( select Id from T_Class where Name='計科一班' )
只有返回且僅返回一行、一列數據的子查詢才能當成單值子查詢。例如咱們上面提到的例子,子查詢中只返回了一個ClassId,這就是單值子查詢。當子查詢跟隨在=、!=、<、<=、>、>=,<> 以後,或子查詢用做表達式,只能使用單值子查詢。
若是子查詢是多行單列的子查詢,這樣的子查詢的結果集實際上是一個集合,那麼可使用in關鍵字代替=號。例如:咱們若是想快速地在T_Student表中刪除計科一班和計科二班的全部學生記錄,咱們可使用in關鍵字:
delete from T_Student where ClassId in ( select Id from T_Class where Name='計科一班' or Name='計科二班' )
exists是用來判斷是否存在的,當exists查詢中的查詢存在結果時則返回真,不然返回假。not exists則相反。
exists作爲where 條件時,是先對where 前的主查詢詢進行查詢,而後用主查詢的結果一個一個的代入exists的查詢進行判斷,若是爲真則輸出當前這一條主查詢的結果,不然不輸出。
exists後面的查詢稱爲相關子查詢,即子查詢的查詢條件依賴於外層父查詢中的某個屬性值,其處理過程通常爲:先取外層查詢中的第一個元組,根據它與內層查詢中的相關屬性值處理內層查詢,若where子句返回true,則將此元組放入結果表中,而後取外層查詢中的下一個元組,重複這個過程直到所有檢查完畢爲止。
例如:咱們有一張人員信息表,裏邊有一我的員類型Id字段(pTypeId),它是一個外鍵,對應着人員類型表的主鍵ptId。若是咱們有如下的SQL語句,使用Exists關鍵字則能夠有以下的理解:
select * from Employee e where exists (select * from EmployeeType et where e.pTypeId=et.ptId)
那麼,在這句SQL的執行過程當中,咱們能夠將其理解爲一個雙重的for循環,外邊是主表的循環遍歷,而後將其放到一個temp變量中,再進入從表的for循環,並與從表的項進行一個一個的按照匹配規則(這裏是e.pTypeId=et.ptId)進行匹配,若是有匹配成功則返回true,而且將這一行記錄放到要返回的結果集中,不然返回false。
這裏假設每頁的頁大小爲10條記錄
(1)若是咱們要獲取第一頁的數據,也就是前10個:
select top 10 * from Account
(2)如今咱們要獲取第一頁以後的數據,也就是第20個~最後一個:
select * from Account where Id not in (select top 10 Id from Account)
(3)如今咱們對第20個~最後一個的數據集中取前10個也就成爲第二頁的數據了:
select top 10 * from Account where Id not in (select top 10 Id from Account)
(4)將上述代碼總結爲分頁代碼,設頁大小爲pageSize,請求頁號爲pageIndex:
select top @pageSize * from Account where Id not in (select top ((@pageIndex-1)*@pageSize) Id from Account)
PS:這種分頁方式的缺點是若是要取不少頁以後的數據,那麼就要取出前面不少頁的ID,查詢開銷較大,執行效率也就低下。
從圖中能夠看出,在小數據量的對比下,Top N的查詢開銷較小。可是在大數據量的對比下,Row_Number的方式會取得更高的查詢效率以及較小的開銷。
(1)SQL Server 2005後增長了Row_Number函數,能夠簡化分頁代碼的實現。首先,Row_Number()是一個排序函數,它能夠生成一個有序的行號(若是單靠ID來排序,中間存在斷層,例如某一個ID行已經被刪除了)。根據MSDN的定義:返回結果集分區內行的序列號,每一個分區的第一行從 1 開始。而排序的標準是什麼呢?這個就要靠緊跟其後的OVER()語句來定義了。這裏咱們能夠經過一個示例來看看,其生成的行號如何。
select *,ROW_NUMBER() OVER(order by Id) as RowNum from Account
(2)根據ROW_NUMBER()的使用,咱們能夠將其應用到分頁上,因而咱們能夠寫出如下的代碼來實現獲取第二頁的數據集:
select * from ( select *,ROW_NUMBER() OVER(Order by Id) as rownum from Account ) as t where t.rownum between 11 and 20 order by t.Id asc
(3)將上述代碼總結爲分頁代碼,設頁大小爲pageSize,請求頁號爲pageIndex:
select * from ( select *,ROW_NUMBER() OVER(Order by Id) as rownum from Account ) as t where t.rownum between (@pageIndex-1)*pageSize+1 and @pageSize*pageIndex order by t.Id asc
默認狀況下,使用Join則表明Inner Join內鏈接,表示兩個表根據某種等值規則進行鏈接。例以下面示例:查詢全部學生的學號、姓名及所在班級
select p.Id,p.Name,c.Name from T_Person p join T_Class c on p.ClassId=c.Id
例如:查詢全部學生(參加及未參加考試的都算)及成績,這裏涉及到學生表及成績表,題目要求參加及未參加考試的都要列出來,因而以學生表爲基準,對成績表進行左鏈接:
select * from Student s left join SC sc on s.S#=sc.S#
能夠經過運行結果圖,看到王二小這個童鞋沒有參加考試,也就沒有成績。
例如:要查詢出全部沒有參加考試(在成績表中不存在的學生)的學生的姓名。因而仍是能夠以學生表爲基準,可是要對成績表進行右鏈接:
select * from Student s right join SC sc on s.S#=sc.S#
此種鏈接在實際應用中不算常見的,但倒是理論基礎,由於它表明了笛卡爾積。其實,全部鏈接方式都會先生成臨時笛卡爾積表,笛卡爾積是關係代數裏的一個概念,表示第一個表的行數乘以第二個表的行數等於笛卡爾積結果集的大小。
select * from Student s cross join SC sc
這裏假如Student表中有10行記錄,SC表中有20行記錄,那麼兩表進行交叉鏈接笛卡爾積運算會獲得10*20=200行記錄的結果集。
從用戶角度來看,一個視圖是從一個特定的角度來查看數據庫中的數據。
從數據庫系統內部來看,一個視圖是由SELECT語句組成的查詢定義的虛擬表。
從數據庫系統內部來看,視圖是由一張或多張表中的數據組成的;從數據庫系統外部來看,視圖就如同一張表同樣,對錶可以進行的通常操做均可以應用於視圖,例如查詢,插入,修改,刪除操做等。
例如,咱們能夠建立一個學生成績詳細信息視圖,對一個須要進行三表鏈接的查詢進行封裝:
create view vw_sc as select s.S#,s.Sname,c.Cname,sc.Score from Student s join SC sc on s.S#=sc.S# join Course c on sc.C#=c.C#
而後,咱們對vw_sc進行select查詢:
(1)視圖在操做上和數據表沒有什麼區別,但二者的差別是其本質是不一樣:數據表是實際存儲記錄的地方,然而視圖並不保存任何記錄。
(2)相同的數據表,根據不一樣用戶的不一樣需求,能夠建立不一樣的視圖(不一樣的查詢語句)。