MySQL 新手入門完整版_第1頁
MySQL 新手入門完整版_第2頁
MySQL 新手入門完整版_第3頁
MySQL 新手入門完整版_第4頁
MySQL 新手入門完整版_第5頁
已閱讀5頁,還剩228頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

MySQL新手入門目錄TOC\h\h(1)重新開始\h(2)數據庫概論和MySQL安裝\h(3)SELECT基礎查詢\h(4)運算式和函數\h(5)JOIN和UNION查詢\h(6)CRUD和資料維護\h(7)字符集和數據庫\h(8)存儲引擎和數據類型\h(9)表格和索引\h(10)子查詢\h(11)視圖\h(12)預處理語句\h(13)存儲過程入門\h(14)存儲過程的變量和流程\h(15)存儲過程進階\h(16)觸發器\h(17)資料庫資訊\h(18)錯誤處理和查詢\h(19)導入和導出數據\h(20)性能\hCoverPageMySQL與SQLMySQL在資訊應用的角色,好像跟三國演義這本著作有點類似。MySQL是目前最普及的資料庫伺服器,可是大家也最不在意它,可能因為它是一套免費的軟體,如果不要對它太過份,它會默默的在電腦中為你服務,在一般情況下都不太會出問題。MySQL跟其它一般的資料庫一樣,同樣支援ANSISQL92,也加入少許MySQL自己特別的指令。不論是網頁或應用程式的開發人員,當你第一次接觸資料庫,學習SQL這種古老的指令,應該不會覺得太難。如果你正要進入開發應用程式的領域,在學習的路上,你會分配給SQL的時間應該也不會太多,因為它跟程式語言比較起來是比較單純一些的。因為MySQL和SQL幾乎是最常見的應用,而且大家也覺得它們是簡單的,當然就不會在它們身上花太多時間。所以慢慢的我們會發現一些情況,有一些應用程式發生的問題,其實是來自MySQL資料庫伺服器和應用程式中的SQL敘述,這些問題相對是比較單純的,只是大家忽略了。例如MySQL提供方便好用的「LIMIT」子句,在應用程式中讓開發人員可以很容易完成一些特定的功能,例如網頁應用程式中的分頁查詢。不過LIMIT子句是MySQL才有的,如果應用程式更換資料庫伺服器,例如Oracle,應用程式就會產生一堆錯誤了。還有資料庫的交易(transaction)管理,MySQL預設的MYISAM儲存引擎并沒有支***易管理,因為比較簡單一些,所以運作的效率也會比較好;如果應用程式需要執行交易管理,就要在建立資料庫的時候指定儲存引擎為InnoDB。各種關于MySQL資料庫管理和SQL的問題,開發人員通常在遇到錯誤的時候,才會開始尋求解決問題的方法。這似乎也是MySQL的宿命,因為我們雖然一直在使用它,可是卻不太重視它,也認為這本來就是合理的,開發人員不應該分配太多時間給它。有一個很明顯的情況,在逛書局的時候,你應該已經看不到只有討論關于MySQL和SQL的書籍了。OCPMySQL5Developer在我們臺灣這里,跟開發人員相關的認證考試,這應該算是最冷門的OCP認證科目之一。這個認證考試的主要內容是MySQL的SQL,通過這個考試的人,表示它具備在應用程式中使用SQL的技能。你應該會覺的這是一個有點詭異的認證考試,它好像沒有存在的必要。對一個有經驗的開發人員來說,使用SQL的技能就像是本來就應該存在的,你甚至已經忘記當初是怎么學會SQL;對一個新手來說,不會有人建議你去買一本關于SQL的書籍來學習這方面的技能,因為可能也買不到了,不過有各種網站提供SQL的學習,認識一些基礎的敘述后,遇到問題再說吧!SQL在目前的環境下,越來越不受到開發人員的關愛,尤其是現在各種關于資料庫應用的框架,例如Hibernate和MyBatis,它們的任務就是要殺死SQL這只遠古巨獸,讓開發人員不用受到SQL的煎熬。我也認為開發應用程式一直是一件很困難的事情,各種越來越進步的科技讓生活更方便,可是應用程式開發技術卻越來越復雜,開發人員必須具備的技能也更多,如果真的能有一種技術可以完全消滅SQL,那絕對是一件非常美好的事情。不過目前的情況應該還是有很多困難,就以大約十年前的應用程式來說,SQL還是一個必要的成員,除非放棄原來已經運作正常的程式,否則你還是要面對這些冗長的SQL敘述。這就是「MySQL超新手入門」系列文章的目的,內容的范圍涵蓋OCPMySQL5Developer認證考試,因為它的范圍也是一個開發人員必須具備的SQL技能。從安裝MySQL資料庫與相關的工具程式開始,到學習所有MySQL提供的SQL,雖然是針對MySQL資料庫撰寫的,不過絕大部份都符合ANSISQL92的標準,也就是在其它資料庫產品也可以正確的運作。內容規劃為19章:數據庫概論與MySQL安裝SELECT基礎查詢表達式和函數JOIN和UNION查詢CRUD和數據維護字符集和數據庫儲存引擎和數據類型表格和索引子查詢視圖預處理語句存儲過程入門存儲過程的變量和流程存儲過程進階觸發器資料庫資訊錯誤處理和查詢導入和導出數據性能在第一章介紹基本的資料庫概念與安裝需要的軟體后,第二章到第五章討論基本的新增、修改、刪除和查詢;第六章到第八章討論資料庫、表格和索引的建立與管理,這個部份的內容會有比較多MySQL獨有的特色;第九章是子查詢;第十章到第十五章討論資料庫進階的應用,這些在其它資料庫產品都會提供類似的技術,例如Oracle的PL/SQL;第十六章到第十九章討論的內容比較偏向于資料庫管理和效率的進階應用,這些也是一個開發人員需要了解的。注:紅樓夢在文學上的重視讓它演變成一門「紅學」,可是紅樓夢的故事與人物對一般人來說,卻不如三國演義來得熟悉目錄\h1、存儲與管理資料\h1.1資料庫管理系統與資料庫伺服器\h1.2資料庫\h2.SQL介紹\h3.MySQLWorkbench\h4.下載與安裝MySQL資料庫\h5.安裝范例資料庫1、存儲與管理資料儲存與管理資料一直是資訊應用上最基本、也是最常見的技術。在還沒有使用電腦來管理你的資料時,你可能會使用這樣的方式來保存世界上所有的國家資料:這樣的作法在生活中是很常見的,例如親友的通訊錄,你可能也會使用一張卡片來記錄一個親友的通訊資料,上面有名字、電話、住址,與所有你想要保存的資料。這種保存資料的方式很直接,也很省錢。不過你應該會遇到這樣的問題:如果你買了一臺電腦,電腦中也安裝了一種工作表的軟體,像這類國家或是親友通訊錄的資料,可能就會用這樣的方式把它們儲存在電腦里面:使用這種工作表來儲存國家資料,當然比用卡片好多了,尤其是想要尋找某個國家的資料,然后修改它的人口數量。雖然方便多了,不過在你查詢國家資料時,可能會有這樣的問題:你不太可能把一個洲的國家資料,儲存為一個工作表檔案;就算你這么作了,如果你想要查詢人口數小于十萬的國家時,你會發現這會是一件很困難的工作。1.1資料庫管理系統與資料庫伺服器在資訊的應用軟體中,「資料庫管理系統」是一種用來儲存與管理資料的軟體,它使用安全、穩定與有效率的方式把資料儲存起來,也可以方便與快速的維護資料。尤其是資料的數量很龐大的時候,使用資料庫管理系統來儲存與管理資料,會是一種令人安心而且比較有效率的方式。資料庫管理系統是一種軟體程式,它主要的工作就是儲存與管理資料,如果你把這個軟體程式安裝在一臺電腦中,這臺電腦就會稱為「資料庫伺服器」:在你有了一臺資料庫伺服器以后,你就可以依照自己的需求,使用資料庫管理系統建立一些資料庫:1.2資料庫在使用資料庫前,要先在資料庫伺服器中建立需要的「資料庫、database」,你會依照自己的需求,建立一個或多個資料庫:各種資料庫伺服器軟體通常會提供一些用戶端軟體程式,讓使用者可以輸入與執行SQL敘述,或是執行管理與設定資料庫的工作:以儲存世界資料的資料庫來說,你想要把世界上所有的國家、城市和語言資料,在這個資料庫中儲存與管理。所以你會針對國家資料的部份,在世界資料庫中建立一個儲存國家資料的「表格、table」:儲存在世界資料庫中的國家資料,隨時可以依照不同的需求,查詢需要的國家資料:除了國家表格外,你還會在世界資料庫中建立儲存城市和語言資料的表格:2.SQL介紹有許多廠商開發各種不同的資料庫管理系統產品,它們都可以執行儲存與管理資料的工作,而且使用的方式都是差不多的。執行資料儲存與管理的工作,主要有建立資料庫與表格,和執行資料的新增、修改、刪除與查詢。想要請資料庫管理系統執行這些工作,你會使用一種叫作「StructuredQueryLanguage、SQL」的敘述,一般會把「SQL」念為「sequel」。SQL在很久以前就已經是一種標準的技術,不同的資料庫管理系統產品,在執行資料庫的工作時,使用的SQL的敘述幾乎是一樣的:SQL有一套國際通用的標準,里面規定了所有執行資料庫工作的SQL敘述要怎么寫,不同的資料庫管理系統產品都會以這套標準為基礎。不過不同的產品通常會增加或修改一些SQL敘述,其它的資料庫管理系統就不認識這些SQL敘述了。與資料庫伺服器相對的是「用戶端、client」,跟資料庫伺服器比起來,用戶端就會比較復雜一些:使用像是Java程式設計技術開發的各種應用程式,例如進銷存系統或會計系統,對資料庫伺服器來說,也算是一種用戶端軟體:不論是哪一種用戶端軟體,它們都是使用SQL敘述跟資料庫溝通:3.MySQLWorkbenchMySQL提供的工具軟體,在這幾年有很大的進步,目前已經把所有常用的軟體整合在一起,稱為MySQLWorkbench,里面包含:SQLDevelopment:SQL開發工具,讓使用者輸入并執行SQL敘述DatabaseDesignModeling:資料庫設計與模型工具DatabaseAdministration:資料庫管理工具DatabaseMigration:資料庫轉換工具SQLDevelopment是這個系列文章使用的工具軟體,使用這個內建的工具,可以很方便輸入需要執行的SQL敘述,并檢視執行后的結果:DatabaseDesignModeling是一個圖形化的資料庫設計工具,可以幫助開發人員設計需要的資料庫,或是產生資料庫模型的文件:DatabaseAdministration可以提供開發人員執行管理MySQL資料庫的基本功能,也可以監控資料庫的狀態:4.下載與安裝MySQL資料庫如果你已經安裝過MySQL資料庫和可以輸入和執行SQL敘述的軟體,接下來的內容就可以忽略,直接到第五節安裝范例資料庫就可以了。MySQL的官方網站目前提供一個完整的安裝程式,在Windows平臺只要下載與安裝一個檔案,就包含資料庫伺服器和所有需要的工具軟體,包含這里需要使用的MySQLWorkbench。你可以到這個連結準備開始下載:\h/downloads/windows/installer/進入這個網站以后,參考下面的說明,下載與儲存完整的安裝檔案:下載完成后,執行安裝程式,選擇開始安裝并同意版權聲明后,在選擇安裝種類的畫面選擇DeveloperDefault:后面的步驟依照畫面的指示,選擇Execute或Next,就會進入開始安裝的步驟。安裝完成后,就可以準備進入設定MySQL資料庫的步驟:依照畫面的指示,選擇Next進入設定資料庫管理員(root)密碼的步驟,輸入一個你自己決定的密碼:依照畫面的指示,選擇Next完成設定資料庫的工作。在最后完成安裝與設定的步驟,勾選StartMySQLWorkbenchafterSetup選項后,選擇Finish結束安裝與設定MySQL資料庫的工作。安裝程式會啟動MySQLWorkbench,依照下面的說明,準備設定資料庫連線的基本資訊:選擇下面畫面說明的按鈕:在出現的對話框中輸入在安裝過程中決定的密碼:選擇TestConnection按鈕:如果出現這樣的畫面,表示可以正確的連線到MySQL資料庫:在MySQLWorkbench主畫面選擇Connect:連線到資料庫后,在左側的World資料庫名稱上點兩下(Doubleclick),會發現World會變成粗體字,表示目前開啟(作用中)的資料庫。在畫面中輸入一個測試的SQL敘述,SELECT*FROMcountry。輸入完后,按下執行敘述的快速鍵Ctrl+Enter,就可以看到所有的國家資料:5.安裝范例資料庫完成前面的安裝與設定工作后,MySQL資料庫伺服器中已經有一個內建的范例資料庫world,后面的文章會使用這個資料庫討論與說明一些主題。不過因為這個資料庫比較簡單一些,所以要請你安裝另外一個范例資料庫,后面的文章討論到一些不同的主題時,就會用到這個額外的范例資料庫。在下面的連結按滑鼠右鍵后,選擇另存連結,下載與儲存一個建立資料庫的SQLScript檔案:\h/u/61562257/cmdev.sql在MySQLWorkbench中選擇File->OpenSQLScript,選擇剛才下載與儲存的檔案,就可以看到像這樣的畫面:在MySQLWorkbench中選擇Query->Execute(AllorSelection),Workbench會花一點時間執行所有的敘述。執行完成后,在資料庫列表區塊的任何空白位置,按滑鼠右鍵后選擇RefreshAll,就可以看到安裝好的新資料庫cmdev:完成所有準備工作,下一篇文章就可以開始進入SQL的世界了。目錄\h1查詢資料前的基本概念\h1.1表格、紀錄與欄位\h1.2認識資料型態\h2查詢敘述\h2.1指定使用中的資料庫\h2.2只有SELECT\h2.3指定欄位與表格\h2.4指定需要的欄位\h2.5數學運算\h2.6別名\h3條件查詢\h3.1比較運算子\h3.2邏輯運算子\h3.3其它條件運算子\h3.4NULL值的判斷\h3.5字串樣式\h4排序\h5限制查詢\h5.1指定回傳紀錄數量\h5.2排除重復紀錄1查詢資料前的基本概念1.1表格、紀錄與欄位表格是資料庫儲存資料的基本元件,它是由一些欄位組合而成的,儲存在表格中的每一筆紀錄就擁有這些欄位的資料。以儲存城市資料的表格「city」來說,設計這個表格的人希望一個城市資料需要包含編號、名稱、國家代碼、區域和人口數量,所以他為「city」表格設計了這些「欄位(column)」:儲存在表格中的每一筆資料稱為「列(row)」或「紀錄(record)」:在設計表格的時候,通常會指定一個欄位為「主索引鍵(primarykey)」:注:主索引鍵會在「第八章、表格與索引」中詳細的討論。1.2認識資料型態資料庫中可以儲存各種不同的資料,SQL提供許多不同的「資料型態」讓你應付這些不同的需求。在開始查詢資料之前,你要先認識最常見、也是最基本的資料型態。第一種是數值,為了更精準的保存數值資料,SQL提供整數與小數兩種數值型態:你可以依照自己的需求,使用儲存的數值資料執行數學運算:常用的資料型態還有「字串」與「日期」:在SQL敘述中使用字串資料的時候,字串資料的前后要使用單引號或雙引號:使用日期資料的時候,MySQL資料庫預設的日期格式是「年-月-日」。與字串資料一樣,前后也要使用單引號或雙引號:注:字串與日期資料型態會在「第七章、儲存引擎與資料型態、欄位資料型態」中詳細的討論。另外一種在資料庫中比較特殊的資料型態是「NULL」,它不像數值、字串或日期資料型態是一個明確的資料,「NULL」是用來表示「不確定」、「未知」或「沒有」的資料:2查詢敘述在執行資料庫的操作中,查詢算是最常見也是最復雜的工作,所以一個查詢敘述所使用到的子句也最多,下列是查詢敘述的基本語法:這一章會討論「SELECT」、「FROM」、「WHERE」、「ORDERBY」和「LIMIT」五個子句組合起來的查詢敘述。其它的子句會在下一章繼續討論。在你使用「SELECT」搭配各種子句來查詢資料時,要特別注意子句使用的順序:就算你每一個子句的寫法都沒有出錯,如果順序不對了:2.1指定使用中的資料庫一個資料庫伺服器可以建立許多需要的資料庫,所以在你執行任何資料庫的操作前,通常要先指定使用的資料庫。下列是指定資料庫的指令:如果你使用「MySQLWorkbench」這類的工具軟體,畫面上看起來會像這樣:2.2只有SELECT一個SQL查詢敘述一定要以「SELECT」子句開始,再搭配其它的子句完成查詢資料的工作。你可以單獨使用「SELECT」子句,只不過這樣的用法跟資料庫一點關系都沒有,它只不過把你輸入的內容顯示出來而已:例如下列的查詢敘述,只是簡單的顯示字串和計算結果,并不會查詢資料庫中的資料:SELECT'MynameisSimonJohnson',35*12

2.3指定欄位與表格一般所謂的查詢敘述,通常是查詢資料庫中的資料,所以「SELECT」子句會搭配「FROM」子句來使用,而「SELECT」后面可以指定「*」表示要查詢指定表格的所有欄位:如果目前使用中的資料庫為「world」,下列的敘述可以查詢「world」資料庫中,「city」表格的所有資料:SELECT*FROMcity

一個資料庫伺服器可以建立許多需要的資料庫,所以在你執行任何資料庫的操作前,都要使用「USE」敘述指定一個使用中的資料庫。不過你也可以在SQL敘述中使用下列的語法來指定資料庫:如果目前使用中的資料庫是「world」,你不用先使用「USEcmdev」敘述切換使用中的資料庫,可以使用下列的語法查詢「cmdev」資料庫中的「emp」表格:SELECT*FROMcmdev.emp

2.4指定需要的欄位有時候你并不需要查詢一個表格中所有的欄位,所以你可以在「SELECT」子句后面自己指定需要的欄位:如果你在「SELECT」后面使用「*」的話:你可以依照自己的需要決定要查詢哪些欄位和順序:2.5數學運算除了查詢表格中的欄位外,你可以加入任何需要的運算,這里先討論一般常見的數學運算。下列是很常用來執行數學運算的運算子:優先順序運算子說明范例運算結果1%余數7%311MOD余數7MOD311*乘7*3211/除7/32.3331DIV除(整數)7DIV322+加7+3102-減7–34注:優先順序的數字從1開始,1表示優先權比較高,2比較低,以此類推。就跟一般數學運算的先乘除后加減一樣:在一個運算式中,優先權高的先算完,再換低優先權繼續算;同樣優先權的就由左到右計算。你也可以在運算式中使用左右括號,括號中的運算會先執行。以「cmdev」資料庫中的員工表格(emp)來說,想要計算員工的年薪,就可以使用這些運算子來完成你的查詢工作:2.6別名你可以另外為「SELECT」后面查詢的資料取一個自己想要的名稱,這個作法稱為「別名(alias

name)」:取欄位別名會讓執行查詢后的結果,使用你自己取的名稱為欄位名稱:注:幫一般欄位取一個欄位別名是比較沒有必要的,如果是運算式的話,通常就要幫它取一個欄位別名來取代原來一大串的運算式。在取欄位別名的時候要特別注意下列的狀況:另外如果你「堅持」要使用SQL語法中的保留字來當作欄位別名的話:如果違反上列兩個規定,執行敘述以后會發生錯誤。3條件查詢使用「SELECT」和「FROM」執行的查詢敘述,是把你在「FROM」子句指定表格里所有的紀錄傳回來。資料庫最大的好處就是可以隨時依照需要查詢部份紀錄資料,你可以搭配「WHERE」子句執行查詢條件的設定:3.1比較運算子要使用「WHERE」執行查詢條件的設定,你會使用下列基礎的比較運算子:|優先順序|運算子|說明|

|1|=|等于|

|1|`|等于||1|

!=|不等于||1|

``|大于||1|

>=`|大于等于|注:``運算子在后面「NULL值的判斷」會討論。使用這些基礎的比較運算子就可以完成一些簡單的條件設定:設定日期資料型態的條件也是很常見的:3.2邏輯運算子查詢條件的設定,有時候會像前面討論的單一條件一樣,并不會太復雜;不過也很常遇到在一個查詢的需求中,需要設定一個以上的條件,那你就會用到下列的運算子:優先順序運算子說明1NOT非2&&而且2AND而且3||

或3OR或3XOR互斥「NOT」運算子比較特殊一些,在一般的需求中,比較不會用到它。以下列的需求來說:如果想要查詢國家代碼是「TWN」,而且人口數量小于十萬的城市,就必須設定兩個條件,而兩個條件之間,依照「而且」的需求,使用「AND」來結合兩個條件:如果想要查詢國家代碼是「TWN」或是「USA」的城市,在兩個條件之間依照「或」的需求,使用「OR」來結合兩個條件:在邏輯運算子的介紹中,它們也同樣有「優先順序」的。如果你想要查詢在歐洲(Europe)或非洲(Aftica)國家,而且人口數要小于一萬。使用下列的查詢條件所得到的資料,跟你想要的卻不一樣:如果有多個查詢條件的設定,全部都是「AND」或全部都是「OR」的話,就沒有這類問題;如果查詢條件中,有「AND」和「OR」同時出現的話,就要依照你的需要,視情況加上左右刮號來控制條件的設定:3.3其它條件運算子一般的條件和邏輯運算子,已經可以應付大部份的查詢條件需求。下列還有一些可以用在特殊用途或是提供替代寫法的條件設定:BETWEEN…AND…:范圍比較IN(…):成員比較IS:是…ISNOT:不是…LIKE:像…「BETWEEN…AND…」用來執行一個指定范圍條件的設定:如果要查詢人口數量在八萬到九萬之間的城市資料,可以有下列兩種條件的寫法,它們執行以后的結果是完全一樣的:使用「BETWEEN…AND…」的條件設定會包含指定的資料,所以下列兩個查詢條件所得到的結果就不一樣了:「BETWEEN…AND…」使用在日期資料時,也可以完成某一個日期范圍的判斷:「IN(…)」使用在一組成員資料的比對條件設定:下列兩個查詢敘述,都可以得到國家代碼是「TWN、USA、JPN、ITA和KOR」的城市資料,可是使用「IN(…)」來設定條件的話,看起來會簡潔很多:3.4NULL值的判斷在國家表格中,有一個儲存平均壽命的欄位「LifeExpectancy」,不過資料庫中的資料并沒有很完整,所以有一些國家是沒有這個資料的,所以會使用「NULL」值來表示:如果想要查詢沒有平均壽命資料的國家,也就是平均壽命的欄位值是「NULL」,你可能會使用下列的敘述:SELECTName,LifeExpectancy

FROMcountry

WHERELifeExpectancy=NULL

上列的敘述執行以后,并沒有傳回任何紀錄,這表示并沒有資料符合你設定的查詢條件。所以「NULL」值的判斷,不可以使用判斷一般資料的條件設定:注:``在判斷一般資料的時候,跟「=」完全一樣;不過它用在判斷「NULL」資料的時候,效果跟「IS」一樣。如果換成要查詢「有」平均壽命資料的國家,也就是平均壽命的欄位值不是「NULL」:3.5字串樣式在使用字串資料的條件判斷時,會有一種很常見、也比較特殊的需求,像是「想要查詢名稱以w字元開始的城市」,如果你使用下列的查詢敘述:SELECTNameFROMcityWHEREName='w'

這樣的查詢條件,當然不是「名稱以w字元開始的城市」,而是名稱只有一個「w」字元的城市。所以這類的查詢就會使用下列這個特殊的條件設定:上列語法中,在「LIKE」后面的「樣版」字串中,會使用到下列兩種「樣版字元」:%:0到多個任何字元_:一個任何字元所以要查詢「名稱以w字元開始的城市」的話:參考上列的作法,就可以延伸出其它的查詢條件設定了:上列的查詢條件中,「w%」表示第一個字元是「w」就符合條件;「%w」表示最后一個字元是「w」就符合條件;最后一個「%w%」表示不論在什么位置有「w」字元,都符合條件。另外一種樣版字元「_」表示一個任何字元:把這些樣版中的底線換到后面的話:你也可以搭配兩種樣版字元完成條件的設定:甚至像查詢「名稱是三十(包含)個字元以上的城市」:注:其實完成上列的查詢條件的需求是不用這么麻煩的,在后面的章節會討論比較簡單的方式。4排序在你執行任何一個查詢以后,MySQL傳回的資料是依照「自然」的順序排列的。所謂的自然順序,通常是資料新增到表格中的順序,可是在資料庫運作一段時間后,陸續會有各種不同的操作,所以這個「自然」順序對你來說,通常是沒什么意義的。一般的查詢通常會有資料排序上的需求,所以你會使用「ORDERBY」子句:如果你希望在查詢城市資料的時候,資料庫會依照國家代碼幫你排序的話:你也可以指定資料排列的順序為由大到小:「ORDERBY」子句后面可以依照需求指定多個排序的資料:「ORDERBY」子句后面指定多個排序資料的時候,都可以依照需求,各自指定資料排列的方式:「ORDERBY」子句指定的資料可以是欄位名稱、編號、運算式或是欄位別名:雖然比較不會有下列這樣的需求,不過你還是可以這樣作:注:資料排列的順序在「第六章、字元集與資料庫」與「第七章、儲存引擎與資料型態」中進一步詳細的討論。5限制查詢5.1指定回傳紀錄數量在你執行一個查詢敘述后,資料庫會將你查詢的資料傳回來給你;如果你使用「WHERE」子句設定查詢條件的話,資料庫就只會傳回符合條件的資料;除了上列的狀況外,你也可以另外使用「LIMIT」子句指定回傳紀錄的數量:如果你在「LIMIT」子句后面指定一個數字:「LIMIT」子句后面也可以指定兩個數字:在查詢敘述中,使用「ORDERBY」子句搭配「LIMIT」子句,就可以完成下列查詢「排名」的工作:注:如果出現類似「…LIMIT1000000,10」這樣的查詢敘述,雖然你只會得到十筆資料,資料庫總共會查詢一百萬零一十筆資料,只不過資料庫會幫你跳過前一百萬筆;類似這樣的需求,還是要使用「WHERE」子句先挑出想要的資料會比較好一些。5.2排除重復紀錄在一個查詢敘述執行以后,資料庫不會幫你檢查回傳的資料是否重復(回傳的兩筆紀錄資料完全一樣),在「SELECT」子句后面可以讓你設定「回傳的資料是否重復」:沒有使用「ALL」或「DISTINCT」的效果,跟你自己加上「ALL」的查詢效果是一樣的,資料庫會依照你的查詢傳回所有的資料:使用「DISTINCT」的話,資料庫會特別執行回傳紀錄是否重復的檢查:目錄\h1值與運算式\h1.1數值\h1.2字串值\h1.3日期與時間值\h1.4NULL值\h2函式\h2.1字串函式\h2.2數學函式\h2.3日期時間函式\h2.4流程控制函式\h2.5其它函式\h3群組查詢\h3.1群組函式\h3.2GROUP_CONCAT函式\h3.3GROUPBY與HAVING子句1值與運算式不論在執行查詢或資料異動的時候,你都可能會使用各種不同種類的值(literalvalues)來完成你的工作:不同種類的值會有不同的用法與規定,可以搭配使用的運算子和函式也不一樣。根據資料類型可以分為下列幾種:數值:可以用來執行算數運算的數值,包含整數與小數,分為精確值與近似值兩種字串:使用單引號或雙引號包圍的文字日期/時間:使用單引號或雙引號包圍的日期或時間空值:使用「NULL」表示的值布林值:「TRUE」或「1」表示「真」,「FALSE」或「0」表示「假」1.1數值數值分為「精確值(exact-value)」與「近似值(approximate-value)」兩種。精確值在使用時不會因為進位而產生差異;使用近似值的時候,可能會因為進位而產生些微的差異。精確值使用一個明確的數字來表示一個整數或小數數值:整數:沒有小數的數字,范圍從-9223372036854775808到9223372036854775807小數:包含小數的數字,整數范圍與上面一樣,小數位數最多可以有30個一般來說,使用精確值在執行各種算數運算的時候,所得到的結果都不會有誤差的問題,你只要特別注意范圍就可以了。例如下列這個比較奇怪的查詢需求:包含小數的數字,在整數部份的限制與整數相同,小數位數會有這樣的限制:近似值的的數字通常稱為「科學表示法」,它使用下列的方式來表示一個數值:這兩種表示方式所代表的數值是這樣計算的:XE+Y,X*10Y,例如5E+3,代表的數字為5000XE-Y,X*10-Y,例如5E-3,代表的數字為0.005注:「XE+Y」格式中的「+」可以省略,例如「5E+3」與「5E3」是一樣的。使用近似值來表示一個數值的時候,你一定要牢記它是一個「近似值」,也就是它真正儲存的數值可能不是你所看到的。下列的情況是你比較容易理解的:不過下列的狀況就會有不一樣的結果:第一個運算值采用精確值的方式,所以它們一定會相等;第二個運算使用近似值的方式,所以它們不一定相等。1.2字串值字串值是以單引號或雙引號包圍的文字資料,就文字資料來說,你不會拿文字執行加、減、乘、除這類的算數運算。如果你拿字串來執行算數運算的話,MySQL會先把字串中的內容轉換為數字,然后再執行算數運算:如果字串內容包含不是數值的文字,MySQL在執行轉換的時候會出現警告訊息:字串與字串可以執行連接的運算,就是把一些字串的內容連接起來后,產生一個新的字串。要執行字串連接的工作,可以使用「||」運算子,這個運算子在條件的判斷中是「或」的意思,如果你直接使用「||」運算子連接字串的話:這是因為在預設的設定下,MySQL把「||」運算子當成數值的「或」運算,所以會出現這樣的情況;你可以透過設定MySQL的SQL模式,來改變這個預設處理方式:SETsql_mode='PIPES_AS_CONCAT'

這個設定會把「||」運算子用在字串值的時候,把它當成「連接」運算子:注:字串的連接也可以使用函式來處理,在這章的后面討論;另外字串的比較因為跟編碼有關,會在后面的章節詳細討論。1.3日期與時間值日期與時間值(temporalvalues)有下列幾種:日期:年年年年-月月-日日,2007-01-01

日期時間:年年年年-月月-日日時時:分分:秒秒,2007-01-0112:00:00

時間:時時:分分:秒秒:12:00:00

在日期與時間值中西元年的部份,可以使用四個或兩個數字。如果指定的兩個數字是「70」到「99」之間,就代表「1970」到「1999」;如果是「00」到「69」之間,就代表「2000」到「2069」。日期值中預設的分隔字元是「-」,你也可以使用「/」,所以「2000-1-1」與「2000/1/1」都是正確的日期值。日期時間資料可以使用在條件的判斷外,也可以用來「運算」,不過當然不是數值的算數運算,而是「一個日期的36天后是哪一天」這類的運算,而且只能使用「+」與「-」的運算。它的語法是:語法中的單位可以使用下列表格中的單位關鍵字:YEAR:年QUARTER:季MONTH:月DAY:日HOUR:時MINUTE:分SECOND:秒注:上列「單位關鍵字」并沒有列出所有的單位關鍵字,全部的單位關鍵字請參考MySQL手冊「12.5.DateandTimeFunctions」。1.4NULL值「NULL」值的處理比任何其它型態的值都來得奇怪一些,它也是一個很常見的資料,可以用來表示「未知的資料」;而且它最特別的地方是「NULL值與其它任何值都不一樣,包含NULL自己」。「NULL」是一個SQL關鍵字,大小寫都可以。你已經知道判斷一個欄位資料是否為「NULL」值的時候,跟其它一般資料判斷是不一樣的;如果算數運算式或比較運算式中有任何「NULL」值的話,結果都會是「NULL」:SELECTNULL=NULL,NULL<NULL,NULL!=NULL,NULL+3

上列的查詢所得到的結果全部都是「NULL」。所以在比較「NULL」值的時侯要使用下列的方式:2函式在你在執行查詢或維護資料的時候,可能會有下列這個比較特殊的需求:以這樣的需求來說,你當然不用自己去計算兩個日期之間的天數,MySQL提供許多不同的函式(functions),可以完成這類的需求,不論在執行查詢或維護的敘述中,都可以使用這些函式。函式基本的用法會像這樣:注:MySQL規定函式預設的寫法是函式名稱和左括號之間不可以有任何空格,否則會造成錯誤;你可以執行SETsql_mode='IGNORE_SPACE'

,這個設定讓你可以在函式名稱和左括號之間加入空格也不會出錯。以上列「計算兩個日期之間的天數」來說,就會在查詢敘述中使用到這樣的函式:MySQL提供的函式非常多,你不用把每一個函式的名稱和用法都背起來,就算是為了參加認證考試也一樣。這個章節只有介紹「部份」函式,并不是全部,所以你在了解這章討論的函式以后,需要到MySQL參考手冊中的「Chapter12.FunctionsandOperators」,進一步認識MySQL還有提供哪一些函式。2.1字串函式字串資料的處理是一種很常見的工作,處理字串的函式也非常多,所以這里使用分類的方式來介紹。下列是處理字串內容的相關函式:LOWER(字串):將[字串]轉換為小寫UPPER(字串):將[字串]轉換為大寫LPAD(字串1,長度,字串2):如果[字串1]的長度小于指定的[長度],就在[字串1]左邊使用[字串2]補滿RPAD(字串1,長度,字串2):如果[字串1]的長度小于指定的[長度],就在[字串1]右邊使用[字串2]補滿LTRIM(字串):移除[字串]左邊的空白RTRIM(字串):移除[字串]右邊的空白TRIM(字串):移除[字串]左、右的空白REPEAT(字串,個數):重復[字串]指定的[個數]REPLACE(字串1,字串2,字串3):將[字串1]中的[字串2]替換為[字串3]「LPAD」與「RPAD」在處理報表資料的時候,很常用來控制報表內容的格式。例如下列的需求:使用「LPAD」函式讓查詢后得到的字串內容向右對齊:下列是截取字串內容的函式:LEFT(字串,長度):傳回[字串]左邊指定[長度]的內容RIGHT(字串,長度):傳回[字串]右邊指定[長度]的內容SUBSTRING(字串,位置):傳回[字串]中從指定的[位置]開始到結尾的內容SUBSTRING(字串,位置,

長度):傳回[字串]中從指定的[位置]開始,到指定[長度]的內容下列是一個測試這些函式的查詢敘述:下列是連接字串的函式:CONCAT(參數[,…]):傳回所有參數連接起來的字串CONCAT_WS(分隔字串,參數[,…]):傳回所有參數連接起來的字串,參數之間插入指定的[分隔字串]你可以使用「||」運算子連接字串,「CONCAT」函式也可以完成同樣的需求。唯一的差異是要先設定「sql_mode」為「PIPES_AS_CONCAT」后,才可以使用「||」運算子連接字串;而「CONCAT」函式不用執行任何設定就可以連接字串。「CONCAT_WS」函式提供一種比較方便的字串連接功能,例如下列這個使用「||」運算子連接字串的查詢敘述:改成使用「CONCAT_WS」函式的話,就會比較簡單一些:注:「CONCAT」與「CONCAT_WS」兩個函式的參數可以接受任何型態的資料,它們都會把全部的資料轉為字串后連接起來;「CONCAT」函式的參數中如果有「NULL」值,結果會是「NULL」;「CONCAT_WS」函式的參數中如果有「NULL」值,「NULL」值會被忽略。下列是取得字串資訊的函式:LENGTH(字串):傳回[字串]的長度(bytes)CHAR_LENGTH(字串):傳回[字串]的長度(字元個數)LOCATE(字串1,字串2):傳回[字串1]在[字串2]中的位置,如果[字串2]中沒有[字串1]指定的內容就傳回0使用「LENGTH」函式可以完成類似「國家名稱長度排行榜」的查詢:注:「LENGTH」與「CHAR_LENGTH」的差異在「第六章、字元集與資料庫」與「第七章、儲存引擎與資料型態」中會詳細的討論。如果有需要的話,你也會搭配許多函式來完成你的工作,例如:上列的敘述可以查詢「名稱是一個單字以上的國家」。2.2數學函式下列是數值舍去與進位的函式:ROUND(數字):四舍五入到整數ROUND(數字,位數):四舍五入到指定的位數CEIL(數字)、CEILING(數字):進位到整數FLOOR(數字):舍去所有小數TRUNCATE(數字,位數):將指定的[數字]舍去指定的[位數]下列是一個測試這些函式的查詢敘述:在這些函式中,「TRUNCATE」函式的用法會比較不一樣:下列是算數運算的函式:PI():圓周率POW(數字1,數字2)、POWER(數字,數字2):[數字1]的[數字2]平方RAND():亂數SQRT(數字):[數字]的平方每次使用「RAND」函式的時候,它都會傳回一個大于等于0而且小于等于1的小數數字,通常會把它稱為「亂數」,這個數值是由MySQL隨機產生的。如果你的敘述中需要一個固定范圍內的亂數,可以搭配「RAND」函式套用下列的公式來產生:使用「RAND」函式也可以完成「隨機查詢」的需求:注:MySQL還有提供的許多不同應用的數學函式,例如三角函式,你可以查詢MySQL參考手冊中的「12.4.2.

MathematicalFunctions」。2.3日期時間函式下列是取得日期與時間的函式:CURDATE():取得目前日期,相同功能:CURRENT_DATE、CURRENT_DATE()CURTIME():取得目前時間,相同功能:CURRENT_TIME、CURRENT_TIME()YEAR(日期):傳回[日期]的年MONTH(日期)數字傳回[日期]的月DAY(日期):傳回[日期]的日,相同功能:DAYOFMONTH()MONTHNAME(日期):傳回[日期]的月份名稱DAYNAME(日期):傳回[日期]的星期名稱DAYOFWEEK(日期):傳回[日期]的星期,1到7的數字,表示星期日、一、二…DAYOFYEAR(日期):傳回[日期]的日數,1到366的數字,表示一年中的第幾天QUARTER(日期):傳回[日期]的季,1到4的數字,代表春、夏、秋、冬EXTRACT(單位FROM日期/時間):傳回[日期]中指定的[單位]資料HOUR(時間):傳回[時間]的時MINUTE(時間):傳回[時間]的分SECOND(時間):傳回[時間]的秒「CURDATE」與「CURTIME」可以取得目前伺服器的日期與時間,搭配其它函式就可以完成下列的「建國最久的國家排行」查詢:「EXTRACT」函式用來取得日期時間資料的指定「單位」,例如日期中的月份,使用的「單位」與這一章之前在「日期與時間值」中討論的一樣,這個函式讓你不用記太多「YEAR」或「MONTH」這類函式的名稱:下列是計算日期與時間的函式:ADDDATE(日期,天數):傳回[日期]在指定[天數]以后的日期ADDDATE(日期,INTERVAL數字單位):傳回[日期]在指定[數字]的[單位]以后的日期ADDTIME(日期時間,INTERVAL數字單位):傳回[日期時間]在指定[數字]的[單位]以后的日期時間SUBDATE(日期,天數):傳回[日期]在指定[天數]以前的日期SUBDATE(日期,INTERVAL數字單位):傳回[日期]在指定[數字]的[單位]以前的日期SUBTIME(日期時間,INTERVAL數字單位):傳回[日期時間]在指定[數字]的[單位]以前的日期時間DATEDIFF(日期1,日期2):計算兩個日期差異的天數在計算日期方面的函式,MySQL也提供兩種不同的用法:上列函式中使用的「單位」與這一章之前在「日期與時間值」中討論的一樣。2.4流程控制函式在處理一般工作的時候,使用各種SQL敘述與函式,通常就可以完成你的需求;可是在實際的應用上,難免會遇到類似下列這樣比較復雜一點的需求:像這種依照條件判斷結果而顯示不同資料的需求,可以使用下列這個「IF」函式來處理:使用「IF」函式可以在查詢的時候,依照員工進公司的日期判斷是資深或是一般員工:如果要依照資深員工與一般員工計算不同的獎金,也可以使用「IF」函式來完成:「IF」函式可以用來判斷一個條件「成立」或「不成立」兩種狀況的需求;但是像下列的需求就不適合使用「IF」函式了:如果要完成多種條件的判斷,就要使用下列的「CASE」語法,它應該不能算是一個函式,因為它的長像實在不像是一個函式:套用上列的語法,就可以判斷出所有員工的新資等級:在「CASE」的語法中,要判斷一種條件就使用一個「WHEN」來完成;如果有「所有條件以外」的情況要處理的話,就可以使用「ELSE」來處理:如果要依照員工新資等級計算不同的獎金,也可以使用「CASE」語法來完成這個需求:「CASE」除了上列介紹的語法外,還有另外一種寫法可以處理一些比較特別的需求,例如下列七大洲的名稱與縮寫對照表:Asia:ASEurope:EUAfrica:AFOceania:OAAntarctica:ANNorthAmerica:NASouthAmerica:SA如果要在SQL敘述中有類似這樣的需求,就可以使用下列這種「CASE」的語法:套用上列的語法就可以完成這樣的查詢:以上列的查詢來說,你也可以換成這樣的寫法:SELECTName,Continent,

CASE

WHENContinent='Asia'THEN'AS'

WHENContinent='Europe'THEN'EU'

WHENContinent='Africa'THEN'AF'

WHENContinent='Oceania'THEN'OA'

WHENContinent='Antarctica'THEN'AN'

WHENContinent='NorthAmerica'THEN'NA'

WHENContinent='SouthAmerica'THEN'SA'

ENDContinentCode

FROMcountry

經由這樣的對照,應該可以很容易看得出來,使用哪一種寫法來完成這個查詢會好一些。2.5其它函式IFNULL(參數,運算式):如果[參數]為NULL就傳回[運算式]的值;否則傳回[參數]的值ISNULL(參數):如果[參數]為NULL就傳回TRUE;否則傳回FALSE當資料庫中有「NULL」資料出現的時候,就可能會發生下列這樣奇怪的結果:所以要得到正確的結果,就要使用「IFNULL」函式來特別處理NULL值的運算:「ISNULL」函式用來判斷一個指定的資料是否為「NULL」,它的效果跟之前在「第二章、基礎查詢、條件比較」中討論的「IS」和「」運算子是一樣的,你可以自己決定要使用哪一種來執行判斷。3群組查詢資料庫通常是用來儲存龐大數量的資料,這也是它最善長跟主要的工作,所以查詢并計算資料的統計分析資訊也是一種很常見的需求:你也可能會進一步的查詢更詳細的統計與分析資訊:3.1群組函式想要完成上列討論的統計與分析查詢,你會用到下列的「群組函式」:MAX(運算式):最大值MIN(運算式):最小值SUM(運算式):合計AVG(運算式):平均COUNT([DISTINCT]|運算式):使用「DISTINCT」時,重復的資料不會計算;使用[]時,計算表格紀錄的數量:使用[運算式]時,計算的數量不會包含「NULL」值使用上列的群組函式可以很容易的查詢需要的統計與分析資訊:這些函式套用在數值資料時會比較明確一些,把它們用在日期資料也是可以完成「員工最早和最晚進公司的日期」的查詢需求:在這些群組函式中,「COUNT」函式的用法會比較不一樣:利用「COUNT」函式的特性,也可以查詢一些特別的資訊:3.2GROUP_CONCAT函式「GROUP_CONCAT」函式是比較特別的一個群組函式,它用來將一些字串資料「串接」起來。在執行一般查詢的時候,會根據查詢的資料,將許多紀錄傳回來給你:使用「GROUP_CONCAT」函式的話,只會回傳一筆紀錄,這筆紀錄包含所有字串資料串接起來的內容:下列是「GROUP_CONCAT」函式的語法:上列的范例是「GROUP_CONCAT」函式最簡單的用法,你還可以在函式中使用與「ORDERBY」子句一樣的用法來指定資料的排列順序:「GROUP_CONCAT」函式連接字串的時候,預設是使用逗號分隔資料,你可以自己指定分隔的字串:在「GROUP_CONCAT」函式中還可以使用類似在「基礎查詢、限制查詢」中討論過的「DISTINCT」來排除重復的資料,例如:在「GROUP_CONCAT」函式中使用「DISTINCT」也會有同樣的效果:3.3GROUPBY與HAVING子句在上列使用群組函式的所有范例中,都是將「FROM」子句中指定的表格當成是一整個「群組」,群組函式所處理的資料是表格中所有的紀錄。如果希望依照指定的資料來計算分組統計與分析資訊,在執行查詢的時候,可能會有下列幾種不同的結果:上列的范例使用「GROUPBY」子句指定分組的設定,下列是分組查詢中的語法:「GROUPBY」子句指定是依照你自己的需求來決定的,同樣以人口數量合計來說,不同的指定可以得到不同的統計資訊:使用不同的群組函式,就可以得不同的資訊:如果需要的話,你可以在一個查詢中,一次取得所有需要的統計與分析資訊:在查詢群組統計與分析資訊的時候,你可以指定多個群組設定取得更詳細的資訊:使用「GROUPBY」指定群組的設定以后,回傳的群組查詢資料都會依照指定的群組排序,預設定排序方式是遞增排序,使用「DESC」關鍵字可以指定排序的方式為遞減排序:使用「GROUPBY」子句的時候可以搭配「WITHROLLUP」:使用「WITHROLLUP」以后,效果會作用在查詢中的每一個群組函式:在「GROUPBY」子句中有多個群組設定的時候,你可以在最后面加入「WITHROLLUP」:在執行群組查詢的時候,一般的條件設定同樣使用「WHERE」子句就可以了:可是以類似上列的查詢來說,把查詢條件從「亞洲的地區」換成「人口合計大于一億的地區」,如果還是把條件設定放在「WHERE」子句的話:包含群組函式的條件設定就一定要放在「HAVING」子句中依照需求在執行群組查詢的時候,應該不會出現下列的查詢敘述:MySQL資料庫在執行上列的查詢敘述后,并不會產生任何錯誤,為了預防這樣的狀況,你可以執行下列的設定:SETsql_mode='ONLY_FULL_GROUP_BY'

在「sql_mode」的設定中加入「ONLY_FULL_GROUP_BY」,表示多了下列的規定:如果查詢敘述違反「ONLY_FULL_GROUP_BY」的規定,就會產生錯誤訊息:目錄\h1使用多個表格\h2InnerJoin\h2.1使用結合條件\h2.2指定表格名稱\h2.3表格別名\h2.4使用「INNERJOIN」\h3OuterJoin\h3.1LEFTOUTERJOIN\h3.2RIGHTOUTERJOIN\h4合并查詢1使用多個表格在「world」資料庫的「country」表格中,儲存世界上所有的國家資料,其中有一個欄位「Capital」用來儲存首都資料,不過它只是儲存一個編號;另外在「city」表格中,儲存世界上所有的城市資料,它主要的欄位有城市編號和城市的名稱:雖然「country」表格自己沒有儲存城市名稱,不過它可以使用「Capital」欄位的值,對照到「city」表格中的「ID」欄位,也可以知道城市的名稱。在這樣的表格設計架構下,如果你想要查詢「所有國家的首都名稱」:這樣的查詢需求就稱為「結合查詢」,也就是你要查詢的資料,來自于一個以上的表格,而且兩個表格之間具有上列討論的「對照」情形。2InnerJoin「Innerjoin」通常稱為「內部結合」,它可以應付大部份的結合查詢需求,內部結合有兩種寫法,差異在把結合條件設定在「WHERE」子句或「FROM」子句中。2.1使用結合條件下列是在「WHERE」子句中設定結合條件來執行結合查詢的語法:雖然這里會先介紹使用結合條件的結合查詢,不過不管使用哪一種寫法,在使用結合查詢時都會有一樣的想法。首先是你想要查詢的欄位:把需要查詢的欄位列在「SELECT」之后,「FROM」子句后面該需要哪一些表格就很清楚了:最后把表格與表格之間「對照」的結合條件放在「WHERE」子句中:這樣的敘述就可以查詢「所有國家的首都名稱」。2.2指定表格名稱在上列的討論中,因為使用到多個表格了,所以在使用表格的欄位時,都特別提醒你要在欄位名稱前面加上表格名稱。其實并不是全部都要指定表格名稱,你只有在一種情況下,才「一定要」在欄位名稱前指定表格名稱:在查詢敘述的「FROM」子句中用到的表格,如果有一樣的欄位名稱,而且你在查詢敘述中也用到了這些欄位,就「一定要」在欄位名稱前指定表格名稱,否則都可以省略:所以省略掉一些表格名稱以后,查詢敘述就簡短多了,不過它執行查詢后的結果也是一樣的:SELECTCode,Capital,city.Name

FROMcountry,city

WHERECapital=ID

如果不小心違反上列的規則,你的查詢敘述在執行以后就會發生錯誤:2.3表格別名如果你想要查詢「國家和首都的人口和比例」:這樣的結合查詢剛好都使用到兩個表格中,有同樣名稱的欄位,所以你一定要指定表格名稱:SELECT,country.PopulationcoPop,

city.Name,city.PopulationciPop,

city.Population/country.Population*100Scale

FROMcountry,city

WHERECapital=ID

這樣的查詢敘述就會比較長一些,也比較容易打錯;所以在結合查詢的敘述中,通常為幫「FROM」子句后面的表格都取一個「表格別名」:使用表格別名以后:幫「FROM」子句中使用到的表格都取一個表格別名,這樣的查詢敘述通常也可以比較簡短一些了。2.4使用「INNERJOIN」執行結合查詢除了使用上列討論的方式外,還有另外一種結合查詢語法:雖然這兩種寫法看起來的差異很大,不過它們的想法會是一樣的。首先是需要查詢的欄位:接下來是需要用到的表格,不過你要使用「INNERJOIN」把兩個表格「結合」起來:最后是結合條件:上列使用「INNERJOIN」的結合查詢執行以后,跟之前使用結合條件的結合查詢,所得到的結果是完全一樣的。所以查詢「國家和首都的人口和比例」的結合查詢,也可以改用下列的寫法:SELECT,a.PopulationcoPop,

b.Name,b.PopulationciPop,

b.Population/a.Population*100

FROMcountryaINNERJOINcitybONCapital=ID

使用「INNERJOIN」的結合查詢還有另外一種選擇:下列是使用「ON」或是「USING」來設定結合條件的情況:所以如果想要查詢「cmdev」資料庫中,員工資料和他們的部門名稱,就會有三種寫法可以選擇了:3OuterJoin在「cmdev」的員工資料(emp)表格中,部門編號(deptno)欄位是用來儲存員工所屬的部門用的;不過有一些員工并沒有部門編號:所以如果你使用「內部結合」的作法執行下列的查詢,你會發現少了兩個員工的資料:這是因為使用「內部結合」的查詢,一定要符合「結合條件」的資料才會出現:如果你想查詢的資料是「包含部門名稱的員工資料,可是沒有分派部門的員工就不用出現了」,那使用「內部結合」就可以完成你的工作了;可是如果你想要查詢的資料是「包含部門名稱的員工資料,沒有分派部門的員工也要出現」,那你就要使用「OUTERJOIN」,這種結合查詢通常稱為「外部結合」:除了多一個「LEFT」或「RIGHT」,還有把「INNER」換成「OUTER」外,其它的部份與內部結合的作法都是一樣的。3.1LEFTOUTERJOIN所以在結合查詢的應用中,如果你想要查詢的資料是「包含部門名稱的員工資料,沒有分派部門的員工也要出現」,也就是希望不符合結合條件的資料也要出現的話,就要換成使用「LEFTOUTERJOIN」來執行結合查詢。OUTERJOIN分為LEFT和RIGHT兩種,在這個范例中,要使用LEFT才符合查詢的需求:3.2RIGHTOUTERJOIN其實使用「LEFTOUTERJOIN」或是「RIGHTOUTERJOIN」并沒有差異,以上列的需求來說,要查詢「包含部門名稱的員工資料,沒有分派部門的員工也要出現」,就是要以「cmdev.emp」表格的資料為主,所以下列兩種寫法所得到的結果是完全一樣的:了解兩種「OUTERJOIN」的后,下列這兩個看起來會有點混淆的查詢,雖然只有「LEFT」與「RIGHT」的差異,它們所完成的查詢需求,卻是完全不一樣的:所以使用「RIGHTOUTERJOIN」的查詢需求,就成為「部門名稱與該部門的員工資料,沒有員工的部門也要出現」:4合并查詢在關聯式資料庫中,因為表格的設計,你常會使用結合查詢來取得需要的資料,結合查詢指的是在「一個」查詢敘述中使用「多個」資料表。而現在要討論的「合并、UNION」查詢,指的是把一個以上的查詢敘述所得到的結果合并為一個,有這樣的需求時,你會在多個查詢敘述之間使用「UNION」關鍵字:以下列這兩個獨立的查詢來說,它們在執行以后會得到各自傳回查詢的紀錄:如果使用「UNION」關鍵字把這兩個查詢合并起來的話,就只會得到一個查詢結果,不過這個查詢結果會包含兩個查詢所得到的紀錄:在執行合并查詢的時候,有一些規則要知道與遵守。第一個規則是回傳結果的欄位名稱:第二個規則是所有查詢敘述的欄位數量一定要一樣:上列的范例比較看不出為什么要使用合并查詢,一般來說,你大概會因為下列的原因,把原來的查詢敘改用合并查詢的寫法來完成你的需求:目錄\h1取得表格資訊\h1.1DESCRIBE指令\h1.2欄位順序\h2新增\h2.1基礎新增敘述\h2.2同時新增多筆紀錄\h2.3索引值\h2.4索引值與ONDUPLICATEKEYUPDATE\h2.5「REPLACE」敘述\h3修改\h3.1搭配「IGNORE」\h3.2搭配「ORDERBY」與「LIMIT」\h4刪除\h4.1「DELETE」敘述\h4.2「TRUNCATE」敘述1取得表格資訊1.1DESCRIBE指令「DESCRIBE」是MySQL資料庫提供的指令,它只能在MySQL資料庫中使用,這個指令可以取得某個表格的結構資訊,它的語法是這樣的:你在MySQL的工具中執行「DESCcmdev.dept」指令以后,MySQL會傳回「cmdev.dept」表格的結構資訊:1.2欄位順序每一個表格在設計的時候,都會決定它有哪一些欄位,和所有欄位的詳細設定。另外也會決定表格中的欄位順序,知道表格欄位順序在接下來的討論中是很重要的:注:如何建立一個新的表格會在「第八章、表格與索引」中討論。2新增2.1基礎新增敘述新增資料到資料庫的表格中使用「INSERT」敘述,下列是這個敘述的基本語法:使用這個語法新增紀錄的時候,要特別注意表格的欄位個數與順序,下列的新增敘述會新增一筆部門的紀錄到「cmdev.dept」表格中:除了明確的指定新增紀錄的每一個欄位資料外,你也可以使用「DEFAULT」關鍵字,讓MySQL為你寫入在設計表格的時候,為欄位指定的預設值。下列的新增敘述同樣會新增一筆部門的紀錄到「cmdev.dept」表格中,不過部門的所在位置(location)欄位值指定為使用預設值:使用這種語法新增紀錄的時候,如果資料個數與欄位個數不一樣的話,就會發生錯誤:資料個數雖然沒有錯,順序卻不對了,也有可能會造成錯誤:新增敘述的另外一種語法,就提供比較靈活的新增紀錄方式,你可以自己指定新增紀錄的欄位個數和順序:在你額外為這個新增敘述指定欄位以后,指定儲存資料的時候就要依照自己指定的欄位個數與順序:如果沒有依照自己指定的欄位個數與順序,就會發生錯誤:因為這種新增敘述的語法可以自己指定欄位的個數與順序,所以你只要指定寫入欄位的資料就可以了。不過要特別注意下列兩種語法的差異:也因為這樣的規定,所以下列這個新增敘述在語法上雖然沒有錯誤,如果違反表格設計上的規定,同樣會造成錯誤:這種新增敘述的語法還有一個比較特別的用法,如果你要新增的紀錄,所有欄位的值都要使用預設值,就可以使用下列的寫法。不過要特別注意下列的新增敘述執行以后會造成錯誤,因為「deptno」與「dname」欄位的預設值是「NULL」,可是它們又不能儲存「NULL」:下列是新增敘述的第三種語法:這種語法只是提供你另外一種新增紀錄的寫法,下列兩個新增敘述的效果是一樣的:2.2同時新增多筆紀錄上列討論的新增敘述執行以后,都是一個敘述新增一筆紀錄,如果需要的話,你也可以在一個新增敘述新增多筆紀錄,差異只有在「VALUES」子句后面新增資料的指定:如果你要新增下列三個員工資料到「cmdev.emp」表格中:

**empno****ename****job****manager****hiredate****salary****comm****deptno**

8001SIMONMANAGER73692001-02-033300NULL50

8002JOHNPROGRAMMER80012002-01-012300NULL50

8003GREENENGINEER80012003-05-012000NULL50

你當然可以分別執行三個新增敘述將三個員工資料新增到「cmdev.emp」表格中;你也可以使用下列一個新增敘述,這個敘述執行以后,同樣會新增三筆紀錄:2.3索引值在設計表格的時候,通常會視需要指定表格中的某一個欄位為「主索引」欄位:注:一個表格除了可以設定「主索引」欄位外,資料庫還提供其它幾種不同的「索引」,索引的應用與設定會在后面「第八章、表格與索引」中詳細討論。如果一個表格設定了某一個欄位為主索引以后,你在新增紀錄時就不可以違反主索引的規定,否則會產生錯誤:你可以在使用「INSERT」敘述的時候,加入「IGNORE」關鍵字,它可以在執行一個違反主索引規定的新增敘述時,自動忽略新增的動作,這樣就不會產生錯誤訊息了:2.4索引值與ONDUPLICATEKEYUPDATE使用「INSERT」敘述新增紀錄的時候,還可以視需要在最后搭配一串關鍵字「ONDUPLICATEKEYUPDATE」,它可以用來指定在違反重復索引值的規定時要執行的修改:需要為「INSERT」敘述搭配「ONDUPLICATEKEYUPDATE」的情況會比較特殊一些,所以接下來會使用「」這個表格來討論它的用法,「」是員工資料庫中用來儲存出差資料的表格,每一個員工到某個地方出差的資料,都會儲存在這個表格中:因為這個表格的設計方式,所以如果要處理編號「7900」的員工到「BOSTON」出差資料的話,你就要執行下列的動作:注:修改敘述「UPDATE」在下一節討論。你會發現要處理員工出差資料會是一件不算簡單的工作,搭配「ONDUPLICATEKEYUPDATE」的「INSERT」敘述,可以讓處理這類需求的敘述比較簡單一些:這個「INSERT」敘述執行以后,資料庫會幫你執行需要的檢查,根據檢查的結果執行不同的動作:2.5「REPLACE」敘述除了使用「INSERT」敘述新增紀錄外,「REPLACE」敘述同樣可以新增紀錄,它們的語法幾乎相同:「INSERT」敘述的另一種寫法也可以套用給「REPLACE」敘述:會使用「REPLACE」敘述新增紀錄的原因,主要還是考慮索引值的情況,「REPLACE」敘述在沒有違反索引值的規定時,效果跟「INSERT」敘述一樣,同樣會新增紀錄到表格中。在發生重復索引值的時候,「INSERT」敘述會發生錯誤:「INSERT」敘述搭配「IGNORE」關鍵字的時候:同樣的情況改用「REPLACE」敘述的話,它會執行修改紀錄的動作:3修改修改已經儲存在表格中的紀錄使用「UPDATE」敘述,下列是它的基本語法:使用「UPDATE」敘述的時候,通常會搭配使用「WHERE」子句,用來指定要修改的紀錄:所以你在執行「UPDATE」敘述的時候,一定要依照實際的需求,正確的設定修改的條件。以下列兩個修改敘述來說,它們執行后的差異是很大的:3.1搭配「IGNORE」在使用「UPDATE」敘述的時候,也可以視需要加入「IGNORE」關鍵字,它可以防止錯誤的修改敘述出現錯誤訊息:除了上列的情況外,你還必須特別注意修改多個欄位值的情況。首先是沒有「IGNORE」關鍵字的時候,錯誤的資料會在執行修改敘述的時候產生錯誤訊息,當然也不會執行任何修改的動作:同樣的修改敘述加入「IGNORE」關鍵字后,執行后的結果可能會跟你想得不太一樣了:3.2搭配「ORDERBY」與「LIMIT」執行修改的時候使用「WHERE」子句是一般最常見的用法,在處理一些比較特殊的修改需求時,也會搭配「ORDERBY」與「LIMIT」子句:「LIMIT」子句也可以在查詢敘述中使用,不過在「UPDATE」敘述中使用「LIMIT」子句會有一個限制:以同樣為員工加薪一百的需求來說,搭配「ORDERBY」與「LIMIT」子句,可以完成許多不同的情況:4刪除4.1「DELETE」敘述刪除表格中不再需要的紀錄使用「DELETE」敘述,下列是它的語法:使用「DELETE」敘述的時候,通常也會使用「WHERE」子句設定要刪除哪些紀錄:執行刪除的時候也可以搭配「ORDERBY」與「LIMIT」子句:4.2「TRUNCATE」敘述如果要刪除一個表格中所有的紀錄,你可以選擇使用「TRUNCATE」敘述,下列是它的語法:要執行刪除表格中所有的紀錄,下列兩個敘述的效果是一樣的:「TRUNCATE」敘述在執行刪除紀錄的時候,會比使用「DELETE」敘述的效率好一些,尤其是表格中的紀錄非常多的時候會更明顯。目錄\h1CharacterSet與Collation\h1.1CharacterSet\h1.2COLLATION\h2資料庫\h2.1建立資料庫\h2.2修改資料庫\h2.3刪除資料庫\h2.4取得資料庫資訊1CharacterSet與Collation任何資訊技術在處理資料的時候,如果只是單純的數值和運算,那就不會有太復雜的問題;如果處理的資料是文字的話,就會面臨世界上各種不同語言的問題。以資料庫來說,它必須正確的儲存各種不同語言的文字,也就是一個資料庫中,有可能同時儲存繁體和簡體中文、法文等不同語言的文字。電腦在處理文字資料大多是使用一個「編碼」來表示某一個字,對MySQL資料庫來說,為了要處理不同語言的文字,它使用一套編碼來

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論