1. 程式人生 > >SQL筆記(二)

SQL筆記(二)

本文章為系列文章,是學習《SLQ必知必會》(Ben Forta 著 人民郵電出版社出版)一書的筆記,因此文中大量引用了原書內容, 所以推薦想系統學習的同學閱讀原書。同時本文所涉及的相關知識及內容版權由《SLQ必知必會》(Ben Forta 著 人民郵電出版社出版)作者所有,如涉及作品內容、版權或其他問題,將在第一時間刪除。本文旨在研究學習使用,禁止用做商業用途。如有其他媒體、網站或個人從本網下載、連線或以其他形式的複製發表、使用所產生的版權等法律問題本站(本人)均不承擔責任。
部落格地址:http://blog.csdn.net/xiaoyuan511

三、排序檢索資料

通過了之前學習的SELECT簡單用法,現在來記錄一下如何使用SELECT語句的ORDER BY子句,也就是根據需要排序檢索出的語句。
在使用ORDER BY子句之前,我們先來看一下什麼是子句。

子句:SQL語句由子句構成,有些句子是必須的,有些是可選的。一個子句通常是由一個關鍵字加上所提供的資料組成。例如:FROM子句。
為了明確的排序通過SELECT語句檢索出的資料,可以使用ORDER BY子句。例如:

SELECT prod_name FROM Products ORDER BY prod_name;

這個會以字母順序排序。(注意:在指定一條ORDER BY

子句時,應該保證它是SELECT 語句中最後一條子句。如果它不是最後的子句,將會出現錯誤訊息。)

同時,在很多時候需要按不止一個列進行資料排序,比如說員工名單,如果多個員工具有相同的姓時,那麼在每個姓中按名排序。要按多個列排序,簡單指定列名,列名之間用逗號分隔。下面這段程式碼是檢索三個列,並按照其中兩個列對結果進行排序——首先按價格,然後按名稱。

SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price, prod_name;

上面這段程式碼的作用是會按照price進行排序,只有當price相同時才會在按照name進行排序。同時也可以按列位置排序,例如:

SELECT prod_id, prod_price, prod_name FROM Products ORDER BY 2, 3;

意思同上,先按照SELECT清單中第二個列prod_price排序,再按第三個列prod_name排序。
同樣,眾所周知在排序上並不是只有升序排序(這個只是預設的排序順序),有時候還要通過ORDER BY進行降序排序,這個時候必須制定DESC關鍵字。例如:

SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC;

這就表示了按價格降序排列。那麼如果打算用多個列排序該怎麼辦呢:

SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price DESC, prod_name;

這樣就可以先按pice降序,而prod_name則仍然按照預設的升序排列。由此可知,DES關鍵字只應用到直接位於其前面的列名,所以如果想在多個列上進行降序排序,必須對每一列指定DESC關鍵字。

四、過濾資料

通過3中排序檢索學習之後,來學習一下如何過濾資料,也就是如何使用SELECT語句
的WHERE子句指定搜尋條件。在SELECT語句中,資料根據WHERE子句中指定的搜尋條件進行過濾。WHERE子句在表名(FROM子句)之後給出,例如:

SELECT prod_name, prod_price FROM Products WHERE prod_price = 3.49;

這條語句代表的意思就是他會檢索prod_name和prod_price兩個列,但是並不會全部返回,只會返回prod_price的值為3.49的值。(如果同時使用ODER BYWHERE子句時,要保證ORDER BY 在 WHERE 之後。)

在上個例子中,我們看到了相等的操作符,那麼他是否支援其他的操作符呢?

操作符 說明
= 等於
<> 不等於
!= 不等於
< 小於
<= 小於等於
!< 不小於
> 大於
>= 大於等於
!> 不大於
BETWEEN…AND 在指定的兩個值之間
IS NULL 為NULL值

在相等的例子之後,我們來看一下其他條件的例子:

1.小於

SELECT prod_name, prod_price FROM Products WHERE prod_price < 10;

2.小於等於

SELECT prod_name, prod_price FROM Products WHERE prod_price <= 10;

3.不匹配檢查(例如:不是DLL01製造的的產品)

SELECT vend_id, prod_name FROM Products WHERE vend_id <> ‘DLL01’;(<> 和 !=可以互換,意義相同)

4.範圍檢查(輸出price值在5~10之間)

SELECT prod_name, prod_price FROM Products WHERE prod_price BETWEEN 5 AND 10;

5.空值檢查(它與欄位包含0、空字串或僅僅包含空格不同,確定值是否為空不能簡單地檢查是否 = NULL,而要用這個 IS NULL子句)

SELECT prod_name FROM Products WHERE prod_price IS NULL;

事例這個就是建廠返回沒有價格(空prod_price欄位,不是價格為0)的產品。

五、高階資料過濾

WHERE的用法並不僅是上面的簡單,他還有很多高階用法,下面我們學習組合WHERE子句。在SQL中,為了進行更強的過濾控制,允許給出多個WHERE子句。這些句子有兩種使用方式,即以AND子句或OR子句的方式使用。

操作符:用來聯結或改變WHERE子句中的子句的關鍵字,也稱為邏輯操作符。

AND操作符:要通過不止一個列進行過濾,可以使用AND操作符給WHERE子句附加條件,例如:

SELECT prod_id, prod_price, prod_nam FROM Products WHERE vend_id = ‘DLL01’ AND prod_price <= 4;

這句話的意思就是檢索出製造商為DLL01且價格小於等於4的商品。同理,可以使用多個過濾條件,每個條件之間都要使用ADN關鍵字。

OR操作符:OR操作符與AND操作符正好相反,它是匹配任一條件的行。比如第一個條件滿足了,那麼他就不會檢索第二個條件,而是會直接輸出,同理,如果第一個條件沒有滿足,但是第二個或者之後的條件滿足了,那麼他同樣會輸出。例如:

SELECT prod_name, prod_price FROM Products WHERE vend_id = ‘DLL01’ OR vend_id = ‘BRS01’;

他會輸出製造商為DLL01或者BRS01的產品。

ADN:用在WHERE子句中的關鍵字,用來指示檢索滿足所有給定條件的行。

OR:用在WHERE子句中的關鍵字,用來表示檢索匹配任一給定條件的行。

過了解上面和AND或OR之後,我們知道WHERE子句可以包含任意數目的AND和OR。那麼,問題來了,同時使用AND和OR的時候,有優先順序之分麼?還是他們兩個是平級的順序?

答案是:AND在求值過程中優先順序更高。因此如下段程式碼:

SELECT prod_name, prod_price FROM Products WHERE vend_id = ‘DLL01’ OR vend_id = ‘BRS01’ AND prod_price >= 10;

這段程式碼的實際意義是,由供應商BRS01製造的prod_price>=10的產品,或製造商為DELL01的全部產品。那麼如果我們想要製造商為DLL01或者BRS01,他們大於10的產品應該怎麼寫呢?

SELECT prod_name, prod_price FROM Products WHERE (vend_id = ‘DLL01’ OR vend_id = ‘BRS01’) AND prod_price >= 10;

答:如同運演算法則一樣,加個括號即可。

(小提示:任何時候在使用具有AND和OR操作符的WHERE 子句,都應該使用括號明確的分組操作符,這樣的話它會盡最大可能消除歧義同時便於理解。)
寫到這裡,又有了疑問了,那就是如果我需要製造商為N家的產品時,那麼我是否需要: xxx OR xxx OR xxx OR xxx…,難道沒有更加簡潔優雅的方法麼?
答案是,有的,可以用IN操作符。

舉個例子:
SELECT prod_name, prod_price FROM Products WHERE vend_id IN (‘DLL01’, ‘BRS01’)

這塊引用書中的原話就是:

  • 在有很多合法選項時,IN操作符的語法更清楚,更直觀。
  • 在與其他AND和OR操作符組合使用IN時,求值順序更容易管理。
  • IN操作符一般比一組OR操作符執行更快。
  • IN的最大優點是可以包含其他SELECT語句,能夠更動態的簡歷WHERE子句。

現在,讓我們來看一下本章要學的最後一個操作符——NOT操作符。

NOT:WHERE 子句中用來否定其後條件的關鍵字。

NOT關鍵字在WHERE子句中有且只有一個功能,就是否定其後所跟的任何條件。因為NOT從來不單獨使用,所以他的語法與其他操作符有所不同。NOT關鍵字可以用在要過濾的列前而不僅是在其後。例如:

SELECT prod_name FROM Products WHERE NOT vend_id = ‘DLLO1’ ORDER BY prod_name;

這個例子的意思就是匹配非DLL01之外所有的東西。(是的,跟之前的!= 或者 <> 一個效果)

六、用萬用字元進行過濾

在經過之前的學習之後,現在來看一下什麼是萬用字元、如何使用萬用字元以及怎樣使用LIKE操作符進行統配搜尋。在之前學習的所有操作符都是針對已知值進行過濾的。但是這種過濾方法不是在任何時候都好用,例如:如何搜尋產品名中包含 bean bag的所有產品?這就可以通過使用萬用字元來實現。

萬用字元:用來匹配值的一部分的特殊字元。

搜尋模式:由字面值、萬用字元或兩者組合構成的搜尋條件。

萬用字元實際上是SQL的WHERE子句中有特殊含義的字元。在搜尋子句中使用萬用字元,必須使用LIKE操作符。(LIKE其實是謂詞不是操作符。。。)

萬用字元搜尋只能用於文字欄位(字串),非文字資料型別欄位不能使用萬用字元搜尋。

百分號(%)萬用字元
最常使用的萬用字元是百分號(%)。在搜尋串中,%表示任何字元出現任意次數。例如:

SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE ‘Fish%’;

以上語句的意思是找出所有已Fish起頭的產品。(根據DBMS配置不同,可以區分大小寫。)
萬用字元可以在搜尋模式中的任意位置使用,並且可以使用多個萬用字元。如下面的例子:

SELECT prod_id,prod_name FROM Products WHERE prod_name LIKE ‘%bean bag%’;

表示匹配任何位置上包含文字bean bag的值,不論它之前或之後出現什麼字元。他也可以在中間使用:

SELECT prod_name FROM Products WHERE prod_name LIKE ‘F%y’;

它代表搜尋以F開頭y結尾的搜尋結果(可以用在查詢一份郵件之類的)。要注意的是,萬用字元%看起來可以匹配任何東西,但是無法匹配NULL。也就是說 WHERE prod_name LIKE ‘%’ 不會匹配產品名稱為NULL的行。

下劃線(_)萬用字元:用途與%一樣,只是匹配單個字:

SELECT prod_name FROM Products WHERE prod_name LIKE ‘__ inch teddy bear’;

他會查詢在 inch teddy bear之前恰好有兩個字元所匹配的項。

書中總結了使用萬用字元的技巧,如下:

  • 不要過度是用萬用字元。如果其他操作符能達到相同的目的,應該使用其他的操作符。
  • 在確實需要使用萬用字元時,也儘量不要把他們用在搜尋模式的開始處。把萬用字元至於開始處,搜尋起來是最慢的。
  • 仔細注意萬用字元的位置。如果放錯地方,可能不會返回想要的資料。