2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

Mysql入門系列:MySQL教程(2)

 krrish 2010-09-11
MySQL允許您一次從多個表中選擇列。我們將這個內(nèi)容留到“從多個表中檢索信息”小節(jié)去介紹。

  1. 指定檢索條件

  為了限制SELECT 語句檢索出來的記錄集,可使用WHERE 子句,它給出選擇行的條件??赏ㄟ^查找滿足各種條件的列值來選擇行。

   可查找數(shù)字值:

  

  也可以查找串值。(注意,一般串的比較是不區(qū)分大小寫的。)

  

  可以查找日期值:

  

  可搜索組合值:

  

  WHERE 子句中的表達式可使用表1-1中的算術運算符、表1-2 的比較運算符和表1-3 的邏輯運算符。還可以使用圓括號將一個表達式分成幾個部分。可使用常量、表列和函數(shù)來完成運算。在本教程的查詢中,我們有時使用幾個MySQL函數(shù),但是MySQL的函數(shù)遠不止這里

  給出的這些。請參閱附錄C,那里給出了所有MySQL函數(shù)的清單。

  

  

  在用表達式表示一個需要邏輯運算的查詢時,要注意別混淆邏輯與運算符與我們平常使用的“與”的含義。假如希望查找“出生在Vi rginia 的總統(tǒng)與出生在Maryland 的總統(tǒng)”。應該注意怎樣表示“與”的關系,能寫成如下的查詢嗎?
 

  錯了,因為這個查詢的意思是“選擇既出生在Vi rginia 又出生在M a r y l a n d的總統(tǒng)”,不可能有同時出生在兩個地點的總統(tǒng),因此這個查詢無意義。在英語中,可以用“a n d”表示這種選擇,但在SQL 中,應該用OR 來連接兩個條件,如下所示:

  

  

  這有時是可以覺察到的,不僅僅是在編寫自己的查詢時可以覺察到,而且在為他人編寫查詢時也可以知道。最好是在他人描述想要檢索什么時仔細聽,但不一定使用相同的邏輯運算符將他人的描述轉錄成SQL 語句。對剛才所舉的例子,正確的英語等價描述為“選擇出生在Vi rginia 或者出生在Maryland 的總統(tǒng)。”

  2. NULL 值

  NULL 值是特殊的;因為它代表“無值”。不可能以評估兩個已知值的相同方式來將它與已知值進行評估。如果試圖與通常的算術比較運算符一道使用NULL,其結果是未定義的:

  

  為了進行NULL 值的搜索,必須采用特殊的語法。不能用= 或!= 來測試等于NULL 或不等于NULL,取而代之的是使用IS NULL 或IS NOT NULL 來測試。例如,因為我們將健在總統(tǒng)的死亡日期表示為NULL,那么可按如下語句查找健在的總統(tǒng):

  
 
 MySQL3.23 及以后的版本具有一個特殊的MySQL專有的比較運算符“ < = >”,即使是NULL 與NULL 的比較,它也是可行的。用這個比較運算符,可將前面的兩個查詢重寫為:

  

  3. 對查詢結果進行排序

  有時我們注意到,在一個表裝入初始數(shù)據(jù)后,對其發(fā)布一條SELECT * FROM tbl_name查詢,檢索出的行與這些行被插入的順序是相同的。但不要認為這種情況是有規(guī)律的。如果在初始裝入表后進行了行的刪除和插入,就會發(fā)現(xiàn)服務器返回表的行次序被改變了。(刪除記錄在表中留下了未使用的“空位”,MySQL在以后插入新記錄時將會試圖對其填補。)缺省時,如果選擇了行,服務器對返回行的次序不作任何保證。為了對行進行排序,可

  使用ORDER BY 子句:

  

  在ORDER BY 子句中,可在列名之后利用ASC 或DESC 關鍵字指定排序是按該列值的升序或降序進行的。例如,為了按倒序(降序)名排列總統(tǒng)名,可如下使用DESC:

  

  如果在ORDER BY 子句中,對某個列名既不指定ASC 又不指定DESC,則缺省的次序為升序。在對可能包含NULL 值的列進行排序時,如果是升序排序, NULL 值出現(xiàn)在最前面,如果是按降序排序,NULL 值出現(xiàn)在最后。

  查詢結果可在多個列上進行排序,而每個列的升序或降序可以互相獨立。下面的查詢從president 表中檢索行,并按出生的州降序、在每個州中再按姓氏的升序對檢索結果進行排序:

  4. 限制查詢結果如果一個查詢返回許多行,但您只想看其中的幾行,則可以利用LIMIT 子句,特別是與ORDER BY 子句結合時更是如此。MySQL允許限制一個查詢的輸出為前n 行。下面的查詢選擇了5 位出生日期最早的總統(tǒng):

  

  如果利用ORDER BY birth DESC 按降序排序,將得到5 位最晚出生的總統(tǒng)。LIMIT 也可以從查詢結果中取出中間部分。為了做到這一點,必須指定兩個值。第一個值為結果中希望看到的第一個記錄(第一個結果記錄的編號為0 而不是1)。第二個值為希望看到的記錄個數(shù)。下面的查詢類似于前面那個查詢,但只顯示從第11行開始的5 個記錄:

  

  自MySQL3.23.2 以來,可按照一個公式來排序查詢結果。例如,利用ORDER BYRAND( ) 與LIMIT 結合,從president 表中隨機抽取一個記錄:

  

  

  5. 計算并命名輸出的列值

  前面的多數(shù)查詢通過從表中檢索值已經(jīng)產(chǎn)生了輸出結果。MySQL還允許作為一個公式的結果來計算輸出列的值。表達式可以簡單也可以復雜。下面的查詢求一個簡單表達式的值(常量)以及一個涉及幾個算術運算符和兩個函數(shù)調用的較復雜的表達式的值:
 

  此查詢把名和姓連接起來,中間間隔一個空格,將總統(tǒng)名形成一個單一字符串,而且將出生城市和州連接在一起,中間隔一個逗號,形成出生地。

  在利用表達式來計算列值時,此表達式被用作列標題。如果表達式很長(如前面的一些查詢樣例中那樣),那么可能會出現(xiàn)一個很寬的列。為了處理這種情況,此列可利用AS name結構來重新命名標題。這樣的名稱為列別名。用這種方法可使上面的輸出更有意義,如下所示:

  

  

  6. 使用日期

  在MySQL中使用日期時要記住的是,在表示日期時首先給出年份。1999 年7 月27 日表示為“1999 - 07 - 27”,而不是像通常那樣表示為“ 07 - 27 - 1999”或“27 - 07 - 1999”。MySQL提供了幾種對日期進行處理的方法??梢詫θ掌谶M行的一些運算如下:

  ■ 按日期排序。(這點我們已經(jīng)看到幾次了。)

  ■ 查找特定的日期或日期范圍。

  ■ 提取日期值的組成部分,如年、月或日。

  ■ 計算日期的差。

  ■ 日期增加或減去一個間隔得出另一日期。

  下面給出一些日期運算的例子。

  為了查找特定的日期,可使用精確的日期值或與其他日期值進行比較,將一個DATE 列與有關的日期值進行比較:

  
為了測試或檢索日期的成分,可使用諸如YEAR( )、MONTH( ) 或DAYOFMONTH( ) 這樣的函數(shù)。例如,可通過查找月份值為3 的日期,找出與筆者出生在相同月份(三月)的總統(tǒng)。

  

  

  為了更詳細,詳細到天,可組合測試MONTH( ) 和DAYOFMONTH( ) 以找出在筆者的生日出生的總統(tǒng):

  

  這是一種可用來生成類似報紙上娛樂部分所刊登的那種“這些人今天過生日”清單的查詢。但是,不必按前面的查詢那樣插入一個特殊的日期。為了查找每年的今天出生的總統(tǒng),只要將他們的生日與C U R R E N T _ DATE 進行比較即可:

  

  可從一個日期減去另一個日期。這樣可以知道日期間的間隔,這對于確定年齡是非常有用的。例如,為了確定哪位總統(tǒng)活得最長,可將其逝世日期減去出生日期。為此,可利用函數(shù)TO _ DAYS( ) 將出生日期和逝世日期轉換為天數(shù),求出差,然后除以365 得出大概的年齡:

  

  此查詢中所用的FLOOR( ) 函數(shù)截掉了年齡的小數(shù)部分,得到一個整數(shù)。得出日期之差,還可以確定相對于某個特定日期有多長時間。這樣可以告訴歷史同盟的會員,他們還有多久就應該更新自己的會員資格了。計算他們的截止日期和當前日期之差,如果小于某個閾值,則不久就需要更新了。下面的查詢是查找需要在60 天內(nèi)更新的會員:

  自MySQL3.22 以來,可使用DATE_ADD( ) 或DATE_SUB( ) 從一個日期計算另一個日期。這些函數(shù)取一個日期及時間間隔并產(chǎn)生一個新日期。例如:

  

  本節(jié)中前面給出的一個查詢選擇70 年代逝世的總統(tǒng),它對選擇范圍的端點使用直接的日期值。該查詢可以利用一個字符串日期和一個由開始日期和時間間隔計算出的結束日期來重寫:

  

  會員更新查詢可根據(jù)DATE_ADD( ) 寫出如下:

  

  本章前面給出了一個查詢?nèi)缦拢_定不久要來檢查但還沒來診所的牙科病人:

  

  現(xiàn)在回過頭來看,讀者會更清楚這個查詢的含義了。

  7. 模式匹配

  MySQL允許查找與某個模式相配的值。這樣,可以選擇記錄而不用提供精確的值。為了進行模式匹配運算,可使用特殊的運算符( LIKE 和NOT LIKE),并且指定一個包含通配符的串。字符“_”匹配任意單個字符,而“%”匹配任意字符序列(包括空序列)。使用L I K E或NOT LIKE 的模式匹配都是不區(qū)分大小寫的。下列模式匹配以“W”或“w”開始的姓:

  
 
 此查詢給出了一個常見的錯誤,它對一個算術比較運算符使用了模式。這種比較成功的惟一可能是相應的列確實包含串“ W %”或“w %”。下列模式匹配任意位置包含“W”或“w”的姓:

  

  

  MySQL還提供基于擴展正規(guī)表達式的模式匹配。正規(guī)表達式在附錄C 的REGEXP 運算符的介紹中描述。

  8. 生成匯總

  MySQL所能做的最有用的事情是濃縮大量的原始數(shù)據(jù)行并對其進行匯總。當學會了利用MySQL來生成匯總時,它就變成了用戶強有力的好幫手了,因為手工進行匯總是一項冗長的、費時的、易出錯的工作。匯總的一種簡單的形式是確定在一組值中哪些值是唯一值。利用DISTINCT 關鍵字來刪除結果中的重復行。例如,總統(tǒng)出生的各個州可按如下找出:

  

  其他的匯總形式涉及計數(shù),可利用COUNT( ) 函數(shù)。如果使用COUNT (*),它將給出查詢所選擇的行數(shù)。如果一個查詢無WHERE 子句,COUNT(*) 將給出表中的行數(shù)。下列查詢給出共有多少人當過美國總統(tǒng):

  

  如果查詢有WHERE 子句,COUNT(*) 將給出此子句選擇多少行。下面的查詢給出目前為止對班級進行了多少次測試:

  
 

  

  COUNT(*) 對選中的行進行計數(shù)。而COUNT(col_name) 只對非NULL 值進行計數(shù)。下面的查詢說明了這些差異:

  

  這表示,總共有41位總統(tǒng),他們中只有一個具有名字后綴,并且大多數(shù)總統(tǒng)都已去世。自MySQL3.23.2 以來,可以將COUNT( ) 與DISTINCT 組合對選擇結果集中不同的值進行計數(shù)。例如,為了對總統(tǒng)出生的不同州進行計數(shù),可執(zhí)行下列查詢:

  

  可以根據(jù)匯總列中單獨的值對計數(shù)值進行分解。例如,您可能根據(jù)下列的查詢結果知道班級中所有學生的人數(shù):

  

  但是,有多少是男孩?有多少是女孩?分別得出男孩、女孩的一種方法是分別對每種性別進行計數(shù):

  

  雖然這個方法可行,但是它很繁鎖而且并不真正適合于可能有許多不同的值的列。考慮一下怎樣以這種方式確定每個州出生的總統(tǒng)人數(shù)。您不得不找出有哪些州,從而不能省略(SELECT DISTINCT state FROM president),然后對每個州執(zhí)行一個SELECT COUNT(*) 查詢。很顯然,有些事是可以簡化的。所幸MySQL可以利用單個查詢對一個列中不同的值進行計數(shù)。因此,針對學生表可以按如下得出男孩和女孩的人數(shù):

  

  如果以這種方法對值計數(shù), GROUP BY 子句是必須的;它告訴MySQL在對值計數(shù)之前怎樣進行聚集。如果將其省去,則要出錯。COUNT(*) 與GROUP BY 一起用來對值進行計數(shù)比分別對每個不同的列值進行計數(shù)有更多的優(yōu)點,這些優(yōu)點是:

  ■ 不必事先知道要匯總的列中有些什么值。

  ■ 不用編寫多個查詢,只需編寫單個查詢即可。

  ■ 用單一查詢就可以得出所有結果,因此可以對結果進行排序。

  前兩個優(yōu)點對于更方便地表示查詢很重要。第三個優(yōu)點也較為重要,因為它提供了顯示

  結果的靈活性。在使用GROUP BY 子句時,其結果是在要分組的列上進行排序的,但是可以

  使用ORDER BY 來按不同的次序進行排序。例如,如果想得到各州產(chǎn)生的總統(tǒng)人數(shù),并按產(chǎn)

  生人數(shù)最多的州優(yōu)先排出,可以如下使用ORDER BY 子句:

  

  

  如果希望進行排序的列是從計算得出的,則可以給該列一個別名,并在ORDER BY 子句中引用這個別名。前面的查詢說明了這一點; COUNT(*) 列的別名為count。引用這樣的列的另一種方法是引用它在輸出結果中的位置。前面的查詢可編寫如下:

  
 我不認為按位置引用列易讀。如果增加、刪除或重新排序輸出列,必須注意檢查ORDER BY子句,并且如果列號改變后還得記住它。別名就不存在這種問題。如果想與計算出來的列一道使用GROUP BY,正如ORDER BY 一樣,應該利用別名或列位置來引用它。下面的查詢確定在一年的每個月中出生的總統(tǒng)人數(shù):

  

  

  如果不想用LIMIT 子句來限制查詢輸出,而是利用查找特定的COUNT( ) 值來達到這個目的,可使用HAVING 子句。下面的查詢給出了產(chǎn)生兩個以上總統(tǒng)的州:

  

  從更為普遍的意義上說,這是一種在要查找的列中重復值時執(zhí)行的查詢類型。HAVING 類似于WHERE,但它是在查詢結果已經(jīng)選出后才應用的,用來縮減服務器實際送到客戶機的結果。除了COUNT( ) 外還有許多匯總函數(shù)。MIN( )、MAX( )、SUM( ) 和AVG( ) 函數(shù)在確定列的最大、最小、總數(shù)和平均值時都非常有用,甚至可以同時使用它們。下面的查詢得出給定的測試和測驗的各種數(shù)字特性。它還給出有多少學分參與了每個值的計算(有的學生可能缺曠或未計入)。

  

  當然,如果您知道這些信息是來自測驗的還是測試的,則它們就會更有意義。但是,為了產(chǎn)生那樣的信息,還需要參考event 表;我們將在下一節(jié)“從多個表中檢索信息”討論這個查詢。匯總信息是很有意思的,因為它們是那么有用,但不太好控制,容易走樣。請看下列查詢:

  

  此查詢選擇已經(jīng)去世的總統(tǒng),按出生地對他們進行分組,并計算出他們逝世時的年齡,計算出平均年齡(每個州的),然后按平均年齡進行排序。換句話說,此查詢按所出生地確定已故總統(tǒng)的平均壽命。但這說明了什么呢?它僅僅說明您可寫該查詢,當然并不說明此查詢是否值得寫。并不是用一個數(shù)據(jù)庫可以做的所有事情都同樣有意義;但是,人們有時在發(fā)現(xiàn)可以利用自己的數(shù)據(jù)庫進行查詢時感到很開心。這可能說明關于轉播運動會的不斷增加的深奧的(空洞的)統(tǒng)計數(shù)據(jù)在過去幾年里正在不斷增多的原因。運動統(tǒng)計者可以使用他們的數(shù)據(jù)庫來計算出某個隊的歷史紀錄,而這些數(shù)字你可能感興趣,也可能毫無興致。

  9. 從多個表中檢索信息

  到目前為止,我們所編寫的查詢都是從單個表中得到數(shù)據(jù)的。現(xiàn)在,我們將進行一件更為有趣的工作。以前筆者曾經(jīng)提到過,關系DBMS 的強大功能在于它能夠將一樣東西與另一樣東西相關聯(lián),因為這樣使得能夠結合多個表中的信息來解答單個表不能解答的問題。本節(jié)介紹怎樣編寫這種查詢。在從多個表中選擇信息時,需要執(zhí)行一種稱為連接( j o i n)的操作。這是因為需要將一個表中的信息與其他表中的信息相連接來得出查詢結果。即通過協(xié)調各表中的值來完成這項工作。

  我們來研究一個例子。在前面的“學分保存方案”小節(jié)中,給出了一個檢索特定日期的測驗或測試學分的查詢,但沒有解釋。現(xiàn)在可以進行解釋了。這個查詢實際涉及到三種連接方法,因此我們分兩步進行研究。第一步,我們構造一個對特定日期的學分進行選擇的查詢,如下所示:

  

  此查詢找出具有給定日期的記錄,然后利用該記錄中的事件ID 查找具有相同事件ID 的學分。對于每個匹配的事件記錄和學分記錄組合,顯示學生ID、學分、日期和事件類型。此查詢在兩個重要方面不同于我們曾經(jīng)編寫過的其他查詢。它們是:

  ■ FROM 子句給出了不止一個表名,因為我們要檢索的數(shù)據(jù)來自不止一個表:

  FROM event,score

  ■ WHERE 子句說明event 和score 表是由每個表中的event_id 值的匹配連接起來的:

  where event.event_id=score.event_id

  請注意,我們是怎樣利用tbl_name.col_name 語法引用列,以便MySQL知道引用的是哪些表的列。(event_id 出現(xiàn)在兩個表中,如果不用表名來限定它的話將會出現(xiàn)混淆。)此查詢中的其他列( date、score、type)可單獨使用而不用表名限定符,因為它們在表中只出現(xiàn)一次,從而不會出現(xiàn)含混。但是,一般在連接中我們對每個列都進行限定以便清晰地表示出每個列是屬于哪個表。在完全限定的形式下,查詢?nèi)缦拢?/p>

  

  從現(xiàn)在起,我們將使用完全限定的形式。第二步,我們利用student 表完成查詢以便顯示學生名。(第一步中查詢的輸出給出了student_id 字段,但是名字更有意義。)名字顯示是利用score 表和student 表兩者都具有student_id 列,使它們中的記錄可被連接這個事實來完成的。最終的查詢?nèi)缦拢?/p>

  
 此查詢與前一個查詢的差別在于:

  ■ student 表被增加到了FROM 子句中,因為除了event 表和score 表外還用到了它。

  ■ student_id 列現(xiàn)在不明確了(因為現(xiàn)在有兩個引用到的表都含有此列),因此必須限定為score.student_id 或student.student_id 以表明使用的是哪個表。

  ■ WHERE 子句有一個附加項,它說明根據(jù)學生ID 將score 表記錄與student 表記錄進行匹配。

  ■ 此查詢是顯示學生名而不是學生ID。(當然,如果愿意的話,可以兩者都顯示。)利用此查詢,可以加入任意日期,得到該日期的學分,用學生名和學分類型完善查詢結果。不一定要了解關于學生ID 或事件ID 的情況。MySQL小心地得出相關的ID 值并利用它們自動地使各表的行相配。

  學分保存方案涉及的另一項工作是匯總學生的缺勤情況。缺勤情況是按學生ID 和日期在absence 表中記錄的。為得到學生名(而不僅僅是ID),我們需要根據(jù)student_id 的值將absence 表連接到student 表。下面的查詢給出了學生的ID 號和名字以及缺勤計數(shù):

  

  注意:雖然我們在GROUP BY 子句中應用了一個限定符,但對于這個查詢來說不是必須的。因為GROUP BY 子句只引用選擇表中(此查詢的前兩行)的列。在該處只有一個名為student_id 的列,因此MySQL知道應該用哪個列。這個規(guī)則對ORDER BY 子句也成立。如果我們希望只了解哪些學生缺過勤,則此查詢所產(chǎn)生的輸出也是有用的。但是,如果我們將此清單交給學校辦公室,他們可能會說,“其他的學生呢?我們需要每個學生的情況。”這是一個稍微有點不同的問題。它表示需要知道學生的缺勤數(shù),即使沒有缺勤的學生也需要知道。因為問題的不同,查詢也應該不同。
為了解決上述問題,使用LEFT JOIN 而不涉及WHERE 子句中的學生ID。LEFT JOIN要求MySQL對從連接首先給出的表中選擇每行生成一個輸出行(即LEFT JOIN 關鍵字左邊給出的表)。由于首先給出student 表,我們得到了每個學生的輸出結果,即使是那些在absence 表中未給出的學生也都包括在輸出中。此查詢?nèi)缦拢?/div>

  

  前面,在“生成匯總”一節(jié)中,我們執(zhí)行了一個查詢,它生成score 表中數(shù)據(jù)的數(shù)值特征。該查詢的輸出列出了事件ID,但不包括學分日期或類型,因為我們不知道怎樣將score 表連接到event 表以得到學分的日期和類型?,F(xiàn)在可以做到了。下面的查詢類似于早先的那個,但是它給出了學分的日期和類型而不只是簡單的數(shù)字事件ID:

  

  可利用諸如COUNT( ) 和AVG( ) 這樣的函數(shù)生成多個列上的匯總,即使這些列來自不同的表也是如此。下面的查詢確定學分數(shù),以及事件日期與學生性別的每種組合的平均學分。

  

  我們可以使用一個類似的查詢來完成學分保存方案的一個任務,即在學期末計算每個學生的總學分。相應的查詢?nèi)缦拢?/p>

  

  不一定要求連接必須用兩個不同的表來完成。這似乎有點奇怪,但是確實可以將一個表連接到其自身。例如,可通過針對每個總統(tǒng)的出生地查看其他各個總統(tǒng)的出生地,確定幾個總統(tǒng)是否出生在相同城市。此查詢?nèi)缦拢?br>

  此查詢有兩個技巧性的東西:

  ■ 我們需要使用同一表的兩個實例,因此建立了表的別名( p 1、p 2),并利用它們無歧義地引用表列。

  ■ 每個總統(tǒng)的記錄與自身相匹配,但是我們不希望在輸出中看到同一總統(tǒng)出再現(xiàn)兩次。WHERE 子句的第二行保證比較的記錄為不同總統(tǒng)的記錄,使記錄不與自身匹配??梢跃帉懸粋€查找出生在同一天的總統(tǒng)的類似查詢。出生日期不能直接比較,因為那樣會錯過出生在不同年份的總統(tǒng)。我們用MONTH( ) 和DAYOFMONTH( ) 來比較出生日期的月和日,相應的查詢?nèi)缦拢?/p>

  

  利用DAYOFYEAR( ) 而不是MONTH( ) 和DAYOFMONTH( ) 將得出一個更為簡單的查詢,但是在比較閏年日期與非閏年日期時將會得出不正確的結果。迄今所執(zhí)行的連接結合了來自那些在某種意義上具有邏輯關系的表中的信息,但是只有您知道該關系無意義。MySQL并不知道(或不關心)所連接的表相互之間是否相關。例如,可將event 表連接到president 表以找出在某個總統(tǒng)生日那天是否進行了測驗或測試,此查詢?nèi)缦拢?/p>

  

  它產(chǎn)生了您所想要的東西。但說明了什么呢?這說明MySQL將愉快地制造出結果,至于這些結果是否有意義它不管。這是因為您使用的是計算機,所以它不能自動地判斷查詢的結果有用或無用。無論如何,我們都必須為自己所做的事負責。

 

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多