Board logo

標題: [教學] (PHP+IIS+MsSQL教學第28篇) 篩選資料的 SQL 指令 [打印本頁]

作者: 小誌    時間: 2010-5-17 16:54     標題: (PHP+IIS+MsSQL教學第28篇) 篩選資料的 SQL 指令

老闆:「我要買’SQL’」,猜一猜老闆會給拿給您什麼?老闆會拿給您一套微軟的「SQL」資料庫軟體!是老闆錯了嗎?不!老闆沒錯,是您的觀念錯了!不要誤以我們所說的「SQL」是微軟的「SQL Server」!

資料庫是一個儲存「大量」資訊的格式化檔案,當我們使用mssql_query()函數來提取資料時,我們操作的對象是「資料表」,不管資料表內的資料是否是您所需要的,每一筆資料都會被抓進來,您所得的資料都是未經過「篩選」的。如何在茫茫的資料叢林中找到你所需的資訊?那就必須透過SQL指令!

只要我們懂得一些淺顯易懂的口語化SQL指令,就可以讓資料庫篩選並提供我們所需要的資料,但前提是:必須懂得使用SQL指令!

本篇教學內容皆以SQL資料庫為使用對象,在下列附檔中有一個SQL資料庫「Student」,主資料檔Student.mdf、記錄檔Student.ldf,請您將檔案複製到您的硬碟裡並附加到SQL Server中,以方便您操作範例時使用。資料庫內的範例資料來自小誌參加技術士檢定考試的公開題庫資料,如有雷同存屬巧合。
[attach]564[/attach]


要什麼?在那裡?
「請幫我找一下關於’PHP’程式設計的書,應該在’電腦程式’的分類裡」,這句話您覺得很特別或很難理解嗎?如果不會,那小誌要恭喜你囉!您真是有學習SQL的天份!因為這句話的句型就是SQL語言的基本句子(其實就是SQL指令),這句話如果轉換為SQL的句子就是「Select PHP From電腦程式」。

「Select … From …」就是SQL裡最基本的句型!「Select」(要什麼)與「From」(在哪裡),這基本的SQL句型作用於資料庫的「資料欄位」與「資料表」:
Select-From句型
  1. Select  資料欄位  From 資料表
複製代碼
例如:我希望從「成績單」資料表中取出「姓名」這個欄位的資料,則我就可以使用下列這個SQL句子:
  1. Select 姓名 From 成績單
複製代碼
上例只會取出資料表中的一個欄位資料,那可不可以一次從資料表中取出多個欄位的資料?當然可以!您可以選取多個欄位,但是欄位名稱與欄位名稱間必須使用「,」逗號隔開,例如從「成績單」資料表中取出「姓名」與「學號」這兩個欄位的資料:
  1. Select 姓名,學號 From 成績單
複製代碼
上兩個範例所使用的Select-Form句型是最簡單的,可是有一個問題耶!如果我要將資料表內的所有欄位資料都列出來那該怎麼辦?很容易,您只要將您要選取的資料欄位以「*(星號)」代替即可:
  1. Select * From 成績單
複製代碼
「*(星號)」就代表了您要選取資料表內全部的欄位資料。


變更欄位名稱
這裡所指的變更欄位名稱並不是更改資料庫內的欄位名稱喔!而是將取得的資料庫資料欄位以我們指定的名稱加以命名:
  1. Select  欄位名稱 AS 自訂名稱  From 資料表
複製代碼
上式的意思是說:從資料庫中選取某個「欄位名稱」的資料,但是,取得的資料放在我們『自訂名稱』的欄位裡。例如,我們要從「通訊錄」資料表中選取「姓名」與「家長」欄位的資料,但是,希望在網頁中顯示的欄位抬頭名稱是『Name』與『Father』,則我們可以將SQL指令撰寫如下:
  1. Select  姓名 As Name,家長 As Father  From  通訊錄
複製代碼
指定如上式的SQL指令,即可見到下圖的結果:
[attach]551[/attach]


變更欄位名稱的格式還有另外一種,不過,這種方式大家比較少用:
  1. Select  自訂名稱=欄位名稱  From 資料表
複製代碼
例如:
  1. Select  Name=姓名,Father=家長 From 通訊錄
複製代碼
欄位運算
如果想將自資料庫欄位取回的資料做運算,並將運算後的結果放置到另一個『自訂名稱』的欄位裡,也是可以利用「As」來做到喔!例如在我們的範例資料庫STUSENTS裡有一個學生「成績單」的資料表,其內容如如圖
[attach]552[/attach]

在「成績單」的資料表內,記錄著學生的「國文」、「英文」、「數學」三項科目的成績,若現在要將三個科目的分數加總(總分),並將加總後的分數放置到自訂名稱的「總分」欄位裡,則我們可以將SQL指令撰寫如下:
  1. Select 姓名,國文,英文,數學, 國文+英文+數學 As 總分 From 成績單
複製代碼
指定如上式的SQL指令,然,即可見到下圖的結果:
[attach]553[/attach]
作者: 小誌    時間: 2010-5-17 17:08

Where條件篩選
Select-Form句型雖然可以依欄位名稱來選取我們需要的欄位資料,但是我們所得的資料是整個資料表中全部資料錄的欄位資料,聽的很模糊喔!小誌以實例來說好了:我只要取得國文分數大於60分的同學成績列表,簡單的一句話要如何轉化為SQL指令?

首先,先完成您所需的欄位資料SQL句子,如果想獲得的全部欄位資料,我們就這樣寫:
  1. Select *  From  成績單
複製代碼
這樣就會取出所有資料表欄位的資料,可是我只要國文分數大於60分的同學成績列表ㄚ,那我們就進階篩選,在「Select …Form…」後面再加上我們的條件「Where 國文>60」:
  1. Select *  From  成績單 Where 國文>60
複製代碼
使用上列的SQL句子向資料庫下命令,即可獲得下圖的結果
[attach]554[/attach]


And 並且
如果我要列表的是國文成績大於90而且英文成績大於90的同學,那我們就再加上邏輯運算子「And」來連接兩個(或多個)條件:
  1. Select *  From  成績單 Where 國文>90 And 英文>90
複製代碼
當我們加上邏輯運算子「And」時,則我們所獲得的資料必須是符合所有條件的資料錄才會被列表出來。
[attach]555[/attach]


Or 或
使用邏輯運算子「And」,是符合所有條件的資料錄才會被列表出來,但是若下了很多的條件式,希望只要符合其中條件的資料就列表出來,那就必須使用邏輯運算子「Or」:
  1. Select *  From  成績單 Where 國文>90 Or 英文>90
複製代碼
上式中國文成績大於90或者英文成績大於90的同學,都會被列表出來。


Between 介於
我要列表的是國文成績大於60而且國文成績小於90的同學,請問您該如何下句子?到目前所學的為止,您應該會這樣寫:
  1. Select *  From  成績單 Where 國文>60 And國文<90
複製代碼
您這樣下指令是對的喔!但是對於相同欄位的資料篩選,這樣的做法比較麻煩,如果是相同欄位的篩選,我們可以用「Between」來完成,例如上例我們就可以改寫如下:(範例ex08_13.php)
  1. Select *  From  成績單 Where 國文 Between 60 And 90
複製代碼
這樣做的好處是:篩選的執行速度較快!因為「國文>60 And國文<90」是使用了三個運算元來篩選,而「Between 60 And 90」只使用了一個運算元。SQL語言視「Between…And…」為一個運算元。
[attach]556[/attach]


Like 近似篩選
我們剛剛所進行的都是「數值」篩選,如果篩選的內容是「文字」該怎麼辦?如果是要找「完全符合」的,同樣是使用「Where」與運算元「=」就行了,例如,我要列表「姓名」為「楊小誌」的資料:
  1. Select *  From  成績單 Where 姓名 = ‘楊小誌’
複製代碼
請注意:「文字」的篩選條件值,必須前後以「’(單引號)」包括起來!上式中,我們所篩選列表的是「姓名」為欄位值完全符合「楊小誌」這個條件值的資料錄,如果我要的是「楊XX」同學的資料列表該如何處理(即列出全部姓’楊’的同學資料)?那就不可以用「=」了,而要改用「Like」關鍵字:
  1. Select *  From  成績單 Where 姓名 Like ‘楊﹪’
複製代碼
上式,您將會獲得「姓名」欄位資料開頭為「楊」這個字的資料錄列表,如果說您要列表的是「姓名」欄位資料中含由「陶」這個字的資料錄,則您應該這樣寫:
  1. Select *  From  成績單 Where 姓名 Like ‘﹪陶﹪
複製代碼

上式,您將會獲得「姓名」欄位資料中任意位置為「陶」這個字的資料錄列表。(範例ex08_14.php)
[attach]557[/attach]


      提示!!
「﹪」百分比符號是一個萬用字元,可代替任意位置、任意長度的文字;除了「﹪」百分比符號外,還有一個「_(Under Line)」底線符號,它也是一個萬用字元,但是它只能代替一個長度的文字!


In 多條件符合
我要列表的是「陳ㄚ扁」、「張雪友」、「彭佳會」這三位同學的資料,請問您該如何下句子?到目前所學的為止,您應該會這樣寫:
  1. Select * From 成績單 Where 姓名=’陳ㄚ扁’ Or姓名=’張雪友’ Or姓名=’彭佳會’
複製代碼
您這樣下指令也是對的喔!但是對於相同欄位的資料篩選,如果是數值資料,我們會用「Between」來完成,那如果是文字資料資則可以使用「In」來完成,例如上例我們就可以改寫如下:
  1. Select * From 成績單 Where 姓名 In (’陳ㄚ扁’,’張雪友’,’彭佳會’)
複製代碼
上式中「姓名」為「陳ㄚ扁」、「張雪友」或「彭佳會」的資料錄,都會被列表出來。
[attach]558[/attach]
作者: 小誌    時間: 2010-5-17 17:11

Order By 排序
雖然使用Where條件式可以依我們的條件定義來選取我們需要的資料,但是我們所得的資料錄順序是沒有特定規則的,例如,我希望同學的成績是按照數學分數的高低來條列(由最低分數排到最高分數),那該如何下指令?

首先,先完成您所需的欄位資料SQL句子,如果想獲得的全部欄位資料,我們就這樣寫:
  1. Select *  From  成績單
複製代碼
這樣就會取出所有資料表欄位的資料,可是我希望同學的成績資料是依照數學分數的高低來排列ㄚ,那我們就加上排序指令「Order By」,在「Select …Form…」後面再加上我們的條件「Order By 數學」:
  1. Select *  From  成績單 Order By 英文
複製代碼
使用上列的SQL句子向資料庫下命令,即可獲得下圖的結果:
[attach]559[/attach]


排序指令「Order By」,並不是只能依據單一的欄位排序,我們也可以同時指定多個欄位為排序依據:
Select *  From  成績單 Order By 國文, 英文 ,數學
上式排序的結果,將會是先依「國文」欄位排序,然後再按照「英文」欄位排序,最後才會依照「數學」欄位排序:
[attach]560[/attach]

Desc 逆向排序
使用排序指令「Order By」來排序時,所得的結果是「從小排到大」,如果我們要「從大排到小」,則可在排序欄位名稱的後面再加上「Desc」指令,例如,依「數學」欄位排序,但是要從分數高的排到分數低的:
  1. Select *  From  成績單 Order By 數學 Desc
複製代碼
使用上列的SQL句子向資料庫下命令,即可獲得下圖的結果:
[attach]561[/attach]
作者: 小誌    時間: 2010-5-17 17:15

Select Top 限制筆數
老師說:本次考試成績,總分為全班前五名者,可獲得獎學金!現在請您將「成績單」資料表內總分為前五名的同學列表出來,這個SQL指令如何下?先把總成績計算出來放在自訂名稱的「總分」欄位裡:
  1. Select 姓名,國文,英文,數學,國文+英文+數學 As 總分 From 成績單
複製代碼
然後,再加入依照總分排序的指令:
  1. Select 姓名,國文,英文,數學,國文+英文+數學 As 總分 From 成績單 Order By 總分
複製代碼
是依照總分排序了沒錯,但卻是由最低分數排到最高分數,得獎的可不是倒數前五名的同學ㄚ!而是要分數最高的前五名同學,因此,要在排序欄位名稱(國文+英文+數學)的後面再加上「Desc」指令,讓排序的結果是「從大排到小」:
  1. Select 姓名,國文,英文,數學, 國文+英文+數學 As 總分  From  成績單 Order By總分
複製代碼
上式SQL指令可獲得下圖結果:
[attach]562[/attach]

Ok!由分數高的排到分數低的了,但是我們只取前五名ㄚ,所以列表的結果只需顯示總分為前五名的同學資料,這時候我們就可以使用「Select Top」指令,將原來的「Select」更改為「Select Top」,並在「Top」之後指定我們要選取的筆數即可:
  1. Select Top 5 姓名,國文,英文,數學, 國文+英文+數學 As 總分  From  成績單 Order By總分Desc
複製代碼
[attach]563[/attach]




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)