最近學習了SQL SERVER方面的知識,畢竟做Web應用,少不了跟數據庫打交道。學習的來源主要是《程序員的SQL金典》這本書。
今天介紹數據庫里面的集合運算符,它是指匹配集合的每一個結果。數據庫集合運算符包括:IN、ANY、SOME、ALL、EISTS及EXCEPT和INTERSECT等。
IN運算符 |
它可以用來匹配一個固定集合中的某一項。比如說一個集合里面的年份有(2001,2003,2005),那么就可以有:
SELECT * FROM T_Book WHERE FYearPublished IN(2001,2003,2005)
IN運算符,除了支持從固定的集合里面去匹配,當然也支持動態的集合方式去匹配。比如如下方式:
SELECT * FROM T_Reader WHERE FYearOfJoin IN ( select FYearPublished FROM T_Book )
ANY和SOME集合運算符 |
在SQL SERVER里面,ANY和SOME是同義詞,二者的用法和功能一樣(一樣還搞兩個,不知道是不是蛋疼)。相比於IN運算符,ANY和SOME需要與其它的比較符(大於(>)、等於(=)、小於(<)、大於等於(>=)、小於等)共同使用,而且比較符需要在它們的前面。
SELECT * FROM T_Reader WHERE FYearOfJoin =ANY ( select FYearPublished FROM T_Book )
注意:和IN 運算符不同,ANY 和SOME運算符不能與固定的集合相匹配,比如下面的SQL 語句是錯誤的:
SELECT * FROM T_Book WHERE FYearPublished<ANY(2001,2003,2005)
ALL集合運算符 |
在SQL SERVER里面,ALL運算符也需要與其它的比較符(大於(>)、等於(=)、小於(<)、大於等於(>=)、小於等)共同使用,而且比較符需要在它們的前面。
SELECT * FROM T_Book WHERE FYearPublished<ALL ( SELECT FYearOfJoin FROM T_Reader )
注意:
I、與ANY和SOME 運算符相同,ALL 運算符同樣不能與固定的集合相匹配,比如下面的SQL 語句是錯誤的:
SELECT * FROM T_Book WHERE FYearPublished<ALL(2001,2003,2005)
II、關於使用ALL運算符,還有一項需要注意,那就是這個ALL子查詢結果為空時,匹配的結果並不是以空的方式來處理,而是相當於全部匹配成功。所以在使用ALL運算符的時候,這一個問題很容易在系統中造成BUG,因此使用時必須注意。比如:
SELECT * FROM T_Book WHERE FYearPublished<ALL ( SELECT FYearOfJoin FROM T_Reader WHERE FProvince = 'JiangSu' )
如果ALL子查詢的結果為空時,則將會取SELECT FYearOfJoin FROM T_Reader的全部結果來作為成功匹配的結果。
EXISTS集合運算符 |
和IN、ANY、SOME、ALL等運算符不同,EXISTS運算符是單目運算符,它不與列匹配,因此它也不要求待匹配的集合是單列的。EXISTS運算符用來檢查每一行是否匹配子查詢,可以認為EXISTS就是用來測試子查詢的結果是否為空,如果結果集為空則匹配結果為false,否則匹配結果為true。
SELECT * FROM T_Category WHERE EXISTS ( SELECT * FROM T_Book WHERE T_Book. FCategoryId = T_Category.FId AND T_Book. FYearPublished<1950 )
在EXISTS后的子查詢中,SQL對T_Category表中的每一行數據到子查詢中進行匹配,測試T_Book 表中是否存在FCategoryId 字段值等於當前類別主鍵值且出版年份在1950 年之前的書籍。
注:EXISTS的子查詢如果為空則返回false,但是如果是直接查詢空,那則會返回true。也就是說下面的例子將會返回表中所有的結果。
SELECT DepartmentID, Name FROM HumanResources.Department WHERE EXISTS (SELECT NULL)
EXCEPT和INTERSECT集合運算符 |
謝謝博友dgdyq提出的意見,在此加上EXCEPT和INTERSECT集合運算符。此處的內容轉載了WizardWu的相關部分來介紹,覺得他介紹得比較好懂。
- EXCEPT: 提取只在 EXCEPT 左側存在,但右側不存在的行,參考下圖 1。用更口語化的說法:「只給我 A 里才有,但 B 里沒有的行」。
- INTERSECT: 只提取兩個結果集里,都存在的行。 INTERSECT 很類似 inner join,但 INTERSECT 並不會對特定的「列 (column)」去做處理。
SELECT ProductID FROM Production.Product EXCEPT SELECT ProductID FROM Production.WorkOrder ;
SELECT ProductID FROM Production.Product INTERSECT SELECT ProductID FROM Production.WorkOrder ;
以上的SQL代碼都為《程序員的SQL金典》(作者:楊中科)例子,書的例子更詳細,大家有興趣的話,可以網上下載PDF文檔看,當然購買正版書也是不錯的選擇。