MYSQL使用手冊 轉自 https://blog.csdn.net/chaoyu168/article/details/50239603
本章通過演示如何使用mysql客戶程式創造和使用一個簡單的資料庫,提供一個MySQL的入門教程。mysql(有時稱為“終端監視器”或只是“監視”)是一個互動式程式,允許你連線一個MySQL伺服器,執行查詢並察看結果。mysql可以用於批模式:你預先把查詢放在一個檔案中,然後告訴mysql執行檔案的內容。本章將介紹使用mysql的兩個方法。
要想檢視由mysql提供的選擇專案表,可以用--help選項來呼叫:
shell> mysql --help
本章假定mysql已經被安裝在你的機器上,並且有一個MySQL伺服器可以連線。否則,請聯絡MySQL管理員。(如果你是管理員,則需要查閱本手冊的其它章節,例如
本章描述建立和使用一個數據庫的全過程。如果你僅僅對訪問一個已經存在的資料庫感興趣,可以跳過描述怎樣建立資料庫及它所包含的表的章節。
由於本章是一個教程,省略了許多細節。關於這裡所涉及的主題的詳細資訊,請查閱本手冊的相關章節。
3.1. 連線與斷開伺服器
為了連線伺服器,當呼叫 mysql時,通常需要提供一個MySQL使用者名稱並且很可能需要一個 密碼。如果伺服器執行在登入伺服器之外的其它機器上,還需要指定主機名。聯絡管理員以找出進行連線所使用的引數 (即,連線的主機、使用者名稱和使用的密碼)。知道正確的引數後,可以按照以下方式進行連線:shell> mysql -h host-u user -p
Enter password: ********
host和user分別代表MySQL伺服器執行的主機名和MySQL賬戶使用者名稱。設定時替換為正確的值。******** 代表你的密碼;當mysql顯示Enter password:提示時輸入它。
如果有效,你應該看見mysql>提示符後的一些介紹資訊:
shell> mysql -h host -u user -p
Enter password: ********
Welcome to the MySQL monitor. Commands end with ; or /g.
Your MySQL connection id is 25338 to server version: 5.1.2-alpha-standard
Type 'help;' or '/h' for help. Type '/c' to clear the buffer.
mysql>
mysql> 提示符告訴你mysql準備為你輸入命令。
一些MySQL安裝允許使用者以匿名(未命名)使用者連線到本地主機上執行的伺服器。如果你的機器是這種情況,你應該能不帶任何選項地呼叫mysql與該伺服器連線:
shell> mysql
成功地連線後,可以在mysql>提示下輸入QUIT (或/q)隨時退出:
mysql> QUIT
Bye
在Unix中,也可以按control-D鍵斷開伺服器。
在下列章節的大多數例子都假設你連線到了伺服器。由mysql>提示指明。
3.2. 輸入查詢
確保你連線上了伺服器,如在先前的章節討論的。連線上伺服器並布代表選擇了任何資料庫,但這樣就可以了。知道關於如何查詢的基本知識,比馬上跳至建立表、給他們裝載資料並且從他們檢索資料更重要。本節描述輸入命令的基本原則,使用幾個查詢,你能嘗試瞭解mysql是如何工作的。
這是一個簡單的命令,要求伺服器告訴它的版本號和當前日期。在mysql>提示輸入如下命令並按回車鍵:
mysql> SELECT VERSION(), CURRENT_DATE;
+-----------------+--------------+
| VERSION() | CURRENT_DATE |
+-----------------+--------------+
| 5.1.2-alpha-log | 2005-10-11 |
+-----------------+--------------+
1 row in set (0.01 sec)
mysql>
這詢問說明mysql的幾個方面:
· 一個命令通常由SQL語句組成,隨後跟著一個分號。(有一些例外不需要分號。早先提到的QUIT是一個例子。後面我們將看到其它的例子。)
· 當發出一個命令時,mysql將它傳送給伺服器並顯示執行結果,然後顯示另一個mysql>顯示它準備好接受其它命令。
· mysql用表格(行和列)方式顯示查詢輸出。第一行包含列的標籤,隨後的行是查詢結果。通常,列標籤是你取自資料庫表的列的名字。如果你正在檢索一個表示式而非表列的值(如剛才的例子),mysql用表示式本身標記列。
· mysql顯示返回了多少行,以及查詢花了多長時間,它給你提供伺服器效能的一個大致概念。因為他們表示時鐘時間(不是 CPU 或機器時間),並且因為他們受到諸如伺服器負載和網路延時的影響,因此這些值是不精確的。(為了簡潔,在本章其它例子中不再顯示“集合中的行”。)
能夠以大小寫輸入關鍵詞。下列查詢是等價的:
mysql> SELECT VERSION(), CURRENT_DATE;
mysql> select version(), current_date;
mysql> SeLeCt vErSiOn(), current_DATE;
這是另外一個查詢,它說明你能將mysql用作一個簡單的計算器:
mysql> SELECT SIN(PI()/4), (4+1)*5;
+------------------+---------+
| SIN(PI()/4) | (4+1)*5 |
+------------------+---------+
| 0.70710678118655 | 25 |
+------------------+---------+
1 row in set (0.02 sec)
至此顯示的命令是相當短的單行語句。你可以在一行上輸入多條語句,只需要以一個分號間隔開各語句:
mysql> SELECT VERSION(); SELECT NOW();
+-----------------+
| VERSION() |
+-----------------+
| 5.1.2-alpha-log |
+-----------------+
1 row in set (0.00 sec)
+---------------------+
| NOW() |
+---------------------+
| 2005-10-11 15:15:00 |
+---------------------+
1 row in set (0.00 sec)
不必全在一個行內給出一個命令,較長命令可以輸入到多個行中。mysql通過尋找終止分號而不是輸入行的結束來決定語句在哪兒結束。(換句話說,mysql接受自由格式的輸入:它收集輸入行但直到看見分號才執行。)
這裡是一個簡單的多行語句的例子:
mysql> SELECT
-> USER()
-> ,
-> CURRENT_DATE;
+---------------+--------------+
| USER() | CURRENT_DATE |
+---------------+--------------+
| [email protected] | 2005-10-11 |
+---------------+--------------+
在這個例子中,在輸入多行查詢的第一行後,要注意提示符如何從mysql>變為->,這正是mysql如何指出它沒見到完整的語句並且正在等待剩餘的部分。提示符是你的朋友,因為它提供有價值的反饋,如果使用該反饋,將總是知道mysql正在等待什麼。
如果你決定不想執行正在輸入過程中的一個命令,輸入/c取消它:
mysql> SELECT
-> USER()
-> /c
mysql>
這裡也要注意提示符,在你輸入/c以後,它切換回到mysql>,提供反饋以表明mysql準備接受一個新命令。
下表顯示出可以看見的各個提示符並簡述它們所表示的mysql的狀態:
提示符 |
含義 |
mysql> |
準備好接受新命令。 |
-> |
等待多行命令的下一行。 |
'> |
等待下一行,等待以單引號(“'”)開始的字串的結束。 |
"> |
等待下一行,等待以雙引號(“"”)開始的字串的結束。 |
`> |
等待下一行,等待以反斜點(‘`’)開始的識別符的結束。 |
/*> |
等待下一行,等待以/*開始的註釋的結束。 |
當你打算在一個單行上發出一個命令時,通常會“偶然”出現多行語句,但是沒有終止分號。在這種情況中,mysql等待進一步輸入:
mysql> SELECT USER()
->
如果出現這種情況(你認為輸完了語句,但是隻有一個->提示符響應),很可能mysql正在等待分號。如果你沒有注意到提示符的提示,在意識到你需要做什麼之前,你可能會呆坐一會兒。輸入一個分號完成語句,mysql將執行:
mysql> SELECT USER()
-> ;
+---------------+
| USER() |
+---------------+
| [email protected] |
+---------------+
在字串收集期間將出現 '> 和 "> 提示符(提示MySQL正等待字串的結束)。在MySQL中,可以寫由‘'’或‘"’字元括起來的字串 (例如,'hello'或"goodbye"),並且mysql允許輸入跨越多行的字串。當看到一個 '> 或 "> 提示符時,這意味著已經輸入了包含以‘'’或‘"’括號字元開始的字串的一行,但是還沒有輸入終止字串的匹配引號。這顯示你粗心地省掉了一個引號字元。例如:
mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
'>
如果你輸入SELECT語句,然後按Enter(回車)鍵並等待結果,什麼都沒有出現。不要驚訝,“為什麼該查詢這麼長呢?”,注意">提示符提供的線索。它告訴你mysql期望見到一個未終止字串的餘下部分。(你看見語句中的錯誤嗎?字串"Smith丟掉了第二個引號。)
走到這一步,你該做什麼?最簡單的是取消命令。然而,在這種情況下,你不能只是輸入/c,因為mysql作為它正在收集的字串的一部分來解釋它!相反,應輸入關閉的引號字元(這樣mysql知道你完成了字串),然後輸入/c:
mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
'> '/c
mysql>
提示符回到mysql>,顯示mysql準備好接受一個新命令了。
`> 提示符類似於 '> 和"> 提示符,但表示你已經開始但沒有結束以`> 開始的識別符。
知道'>和">提示符的含義很重要,因為如果你錯誤地輸入一個未終止的字串,任何後面輸入的行將要被mysql忽略--包括包含QUIT的行!這可能令人相當困惑,特別是如果取消當前命令前還不知道你需要提供終止引號。
3.3. 建立並使用資料庫
知道怎樣輸入命令,便可以訪問資料庫了。
假定在你的家(你的“動物園”)中有很多寵物,並且你想跟蹤關於它們各種型別的資訊。你可以通過建立表來儲存你的資料並根據所需要的資訊裝載他們,然後你可以從表中檢索資料來回答關於動物不同種類的問題。本節顯示如何做到所有這些事情:
· 建立資料庫
· 建立資料庫表
· 裝載資料到資料庫表
· 以各種方法從表中檢索資料
· 使用多個表
動物園資料庫很簡單(特意的),但是不難把它想象成可能用到類似資料庫的真實世界情況。例如,農夫可以使用這樣的一個數據庫來追蹤家畜,或者獸醫可以用它跟蹤病畜記錄。從MySQL網址上可以獲得後面章節中將用到的含有部分查詢和樣例資料的動物園分發。有tar壓縮格式 (http://downloads.mysql.com/docs/menagerie-db.tar.gz)和Zip壓縮格式 (http://downloads.mysql.com/docs/menagerie-db.zip)。
使用SHOW語句找出伺服器上當前存在什麼資料庫:
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql |
| test |
| tmp |
+----------+
可能你的機器上的資料庫列表是不同的,但是很可能有mysql和test資料庫。mysql是必需的,因為它描述使用者訪問許可權,test資料庫經常作為使用者試身手的工作區。
請注意如果沒有SHOW DATABASES許可權,則不能看見所有資料庫。參見13.5.1.3節,“GRANT和REVOKE語法”。
如果test資料庫存在,嘗試訪問它:
mysql> USE test
Database changed
注意,USE,類似QUIT,不需要一個分號。(如果你喜歡,你可以用一個分號終止這樣的語句;這無礙)USE語句在使用上也有另外一個特殊的地方:它必須在一個單行上給出。
你可列在後面的例子中使用test資料庫(如果你能訪問它),但是你在該資料庫建立的任何東西可以被訪問它的其它人刪除,因此,你應該詢問MySQL管理員許可你使用自己的一個數據庫。假定你想要呼叫你的menagerie,管理員需要執行這樣一條命令:
mysql> GRANT ALL ON menagerie.* TO 'your_mysql_name'@'your_client_host';
這裡your_mysql_name是分配給你的MySQL使用者名稱,your_client_host是所連線的伺服器所在的主機。
3.3.1. 建立並選擇資料庫
如果管理員在設定許可權時為你建立了資料庫,你可以開始使用它。否則,你需要自己建立資料庫:mysql> CREATE DATABASE menagerie;
在Unix下,資料庫名稱是區分大小寫的(不像SQL關鍵字),因此你必須總是以menagerie訪問資料庫,而不能用Menagerie、MENAGERIE或其它一些變數。對錶名也是這樣的。(在Windows下,該限制不適用,儘管你必須在一個給定的查詢中使用同樣的大小寫來引用資料庫和表。但是,由於多種原因,作為最好的慣例,一定要使用與資料庫建立時的同樣的大小寫。)
建立資料庫並不表示選定並使用它,你必須明確地操作。為了使menagerie成為當前的資料庫,使用這個命令:
mysql> USE menagerie
Database changed
資料庫只需要建立一次,但是必須在每次啟動mysql會話時在使用前先選擇它。你可以根據上面的例子執行一個USE語句來實現。還可以在呼叫mysql時,通過命令列選擇資料庫,只需要在提供連線引數之後指定資料庫名稱。例如:
shell> mysql -h host -u user -p menagerie
Enter password: ********
注意,剛才顯示的命令列中的menagerie不是你的 密碼。如果你想要在命令列上在-p選項後提供 密碼,則不能插入空格(例如,如-pmypassword,不是-p mypassword)。但是,不建議在命令列輸入密碼,因為這樣會暴露 密碼,能被在機器上登入的其它使用者窺探到。
3.3.2. 建立表
建立資料庫是很容易的部分,但是在這時它是空的,正如SHOW TABLES將告訴你的:
mysql> SHOW TABLES;
Empty set (0.00 sec)
較難的部分是決定你的資料庫結構應該是什麼:你需要什麼資料庫表,各資料庫表中有什麼樣的列。
你將需要一個包含你每個寵物的記錄的表。它可稱為pet表,並且它應該包含,最少,每個動物的名字。因為名字本身不是很有趣,表應該包含另外的資訊。例如,如果在你豢養寵物的家庭有超過一個人,你可能想要列出每個動物的主人。你可能也想要記錄例如種類和性別的一些基本的描述資訊。
年齡呢?那可能有趣,但是儲存到一個數據庫中不是一件好事情。年齡隨著時間流逝而變化,這意味著你將要不斷地更新你的記錄。相反, 儲存一個固定值例如生日比較好,那麼,無論何時你需要年齡,可以以當前日期和出生日期之間的差來計算它。MySQL提供了日期運算函式,因此這並不困難。儲存出生日期而非年齡還有其它優點:
· 你可以使用資料庫完成這樣的任務,例如生成即將到來的寵物生日的提示。(如果你認為這類查詢有點蠢,注意,這與從商務資料庫來識別出不久要發給生日祝賀的客戶是同一個問題,因為計算機幫助私人聯絡。)
· 你可以相對於日期而不止是當前日期來計算年齡。例如,如果你在資料庫儲存死亡日期,你能很容易地計算出一隻寵物死時有多大。
你可能想到pet表中其它有用的其它型別資訊,但是到目前為止這些已經足夠了:名字、主人、種類,性別、出生和死亡日期。
使用一個CREATE TABLE語句指定你的資料庫表的佈局:
mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
-> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
VARCHAR適合於name、owner和species列,因為列值是變長的。這些列的長度不必都相同,而且不必是20。你可以挑選從1到65535的任何長度,從中選擇一個最合理的值。(如果選擇得不合適,後來證明你需要一個更長的欄位,MySQL提供一個ALTER TABLE語句。)
可以用多種型別的值來表示動物記錄中的性別,例如,"m"和"f",或"male"和"female"。使用單字元"m"和"f"是最簡單的方法。
很顯然,birth和death列應選用DATE資料類。
建立了資料庫表後,SHOW TABLES應該產生一些輸出:
mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| pet |
+---------------------+
為了驗證你的表是按你期望的方式建立,使用一個DESCRIBE語句:
mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name | varchar(20) | YES | | NULL | |
| owner | varchar(20) | YES | | NULL | |
| species | varchar(20) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| birth | date | YES | | NULL | |
| death | date | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
你可以隨時使用DESCRIBE,例如,如果你忘記表中的列的名稱或型別時。
3.3.3. 將資料裝入表中
建立表後,需要填入內容。通過LOAD DATA和INSERT語句可以完成該任務。
假定你的寵物紀錄描述如下。(假定在MySQL中期望的日期格式是YYYY-MM-DD;這可能與你習慣的不同。)
name |
owner |
species |
sex |
birth |
death |
Fluffy |
Harold |
cat |
f |
1993-02-04 |
|
Claws |
Gwen |
cat |
m |
1994-03-17 |
|
Buffy |
Harold |
dog |
f |
1989-05-13 |
|
Fang |
Benny |
dog |
m |
1990-08-27 |
|
Bowser |
Diane |
dog |
m |
1979-08-31 |
1995-07-29 |
Chirpy |
Gwen |
bird |
f |
1998-09-11 |
|
Whistler |
Gwen |
bird |
|
1997-12-09 |
|
Slim |
Benny |
snake |
m |
1996-04-29 |
|
因為你是從一個空表開始的,填充它的一個簡易方法是建立一個文字檔案,每個動物各一行,然後用一個語句將檔案的內容裝載到表中。
你可以建立一個文字檔案“pet.txt”,每行包含一個記錄,用定位符(tab)把值分開,並且以CREATE TABLE語句中列出的列次序給出。對於丟失的值(例如未知的性別,或仍然活著的動物的死亡日期),你可以使用NULL值。為了在你的文字檔案中表示這些內容,使用/N(反斜線,字母N)。例如,Whistler鳥的記錄應為(這裡值之間的空白是一個定位符):
name |
owner |
species |
sex |
birth |
death |
Whistler |
Gwen |
bird |
/N |
1997-12-09 |
/N |
要想將文字檔案“pet.txt”裝載到pet表中,使用這個命令:
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;
請注意如果用Windows中的編輯器(使用/r/n做為行的結束符)建立檔案,應使用:
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet
-> LINES TERMINATED BY '/r/n';
(在執行OS X的Apple機上,應使用行結束符'/r'。)
如果你願意,你能明確地在LOAD DATA語句中指出列值的分隔符和行尾標記,但是預設標記是定位符和換行符。這對讀入檔案“pet.txt”的語句已經足夠。
如果該語句失敗,可能是你安裝的MySQL不與使用預設值的本地檔案相容。關於如何更改請參見5.6.4節,“LOAD DATA LOCAL安全問題”。
如果想要一次增加一個新記錄,可以使用INSERT語句。最簡單的形式是,提供每一列的值,其順序與CREATE TABLE語句中列的順序相同。假定Diane把一隻新倉鼠命名為Puffball,你可以使用下面的INSERT語句新增一條新記錄:
mysql> INSERT INTO pet
-> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
注意,這裡字串和日期值均為引號擴起來的字串。另外,可以直接用INSERT語句插入NULL代表不存在的值。不能使用LOAD DATA中所示的的/N。
從這個例子,你應該能看到涉及很多的鍵入用多個INSERT語句而非單個LOAD DATA語句裝載你的初始記錄。
3.3.4. 從表檢索資訊
- 3.3.4.1. 選擇所有資料
- 3.3.4.2. 選擇特殊行
- 3.3.4.3. 選擇特殊列
- 3.3.4.4. 分類行
- 3.3.4.5. 日期計算
-
3.3.4.6. NULL值操作
- 3.3.4.7. 模式匹配
- 3.3.4.8. 計數行
-
3.3.4.9. 使用1個以上的表
SELECT what_to_select
FROM which_table
WHERE conditions_to_satisfy;
what_to_select指出你想要看到的內容,可以是列的一個表,或*表示“所有的列”。which_table指出你想要從其檢索資料的表。WHERE子句是可選項,如果選擇該項,conditions_to_satisfy指定行必須滿足的檢索條件。
3.3.4.1. 選擇所有資料
SELECT最簡單的形式是從一個表中檢索所有記錄:mysql> SELECT * FROM pet;
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Fang | Benny | dog | m | 1990-08-27 | NULL |
| Bowser | Diane | dog | m | 1979-08-31 | 1995-07-29 |
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
| Slim | Benny | snake | m | 1996-04-29 | NULL |
| Puffball | Diane | hamster | f | 1999-03-30 | NULL |
+----------+--------+---------+------+------------+------------+
如果你想要瀏覽整個表,可以使用這種形式的SELECT,例如,剛剛裝載了初始資料集以後。也有可能你想到Bowser的生日看起來不很對。查閱你原來的家譜,你發現正確的出生年是1989,而不是1979。
至少有兩種修正方法:
· 編輯檔案“pet.txt”改正錯誤,然後使用DELETE和LOAD DATA清空並重新裝載表:
· mysql> DELETE FROM pet;
· mysql> LOAD DATA LOCAL INFILE 'pet.txt' INTO TABLE pet;
然而, 如果這樣操做,必須重新輸入Puffball記錄。
· 用一個UPDATE語句僅修正錯誤記錄:
· mysql> UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';
UPDATE只更改有問題的記錄,不需要重新裝載資料庫表。
3.3.4.2. 選擇特殊行
如上所示,檢索整個表是容易的。只需要從SELECT語句中刪掉WHERE子句。但是一般你不想看到整個表,特別地當表變得很大時。相反,你通常對回答一個具體的問題更感興趣,在這種情況下在你想要的資訊上進行一些限制。讓我們看一些他們回答的有關你寵物的問題的選擇查詢。可以從表中只選擇特定的行。例如,如果你想要驗證你對Bowser的生日所做的更改,按下述方法選擇Bowser的記錄:
mysql> SELECT * FROM pet WHERE name = 'Bowser';
+--------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+
輸出證實正確的年份記錄為1989,而不是1979。
字串比較時通常對大小些不敏感,因此你可以將名字指定為"bowser"、"BOWSER"等,查詢結果相同。
你可以在任何列上指定條件,不只僅僅是name。例如,如果你想要知道哪個動物在1998以後出生的,測試birth列:
mysql> SELECT * FROM pet WHERE birth > '1998-1-1';
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Puffball | Diane | hamster | f | 1999-03-30 | NULL |
+----------+-------+---------+------+------------+-------+
可以組合條件,例如,找出雌性的狗:
mysql> SELECT * FROM pet WHERE species = 'dog' AND sex = 'f';
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
上面的查詢使用AND邏輯操作符,也有一個OR操作符:
mysql> SELECT * FROM pet WHERE species = 'snake' OR species = 'bird';
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
| Slim | Benny | snake | m | 1996-04-29 | NULL |
+----------+-------+---------+------+------------+-------+
AND和OR可以混用,但AND比OR具有更高的優先順序。如果你使用兩個操作符,使用圓括號指明如何對條件進行分組是一個好主意:
mysql> SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm')
-> OR (species = 'dog' AND sex = 'f');
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
3.3.4.3. 選擇特殊列
如果你不想看到表中的所有行,就命名你感興趣的列,用逗號分開。例如,如果你想要知道你的動物什麼時候出生的,選擇name和birth列:mysql> SELECT name, birth FROM pet;
+----------+------------+
| name | birth |
+----------+------------+
| Fluffy | 1993-02-04 |
| Claws | 1994-03-17 |
| Buffy | 1989-05-13 |
| Fang | 1990-08-27 |
| Bowser | 1989-08-31 |
| Chirpy | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim | 1996-04-29 |
| Puffball | 1999-03-30 |
+----------+------------+
找出誰擁有寵物,使用這個查詢:
mysql> SELECT owner FROM pet;
+--------+
| owner |
+--------+
| Harold |
| Gwen |
| Harold |
| Benny |
| Diane |
| Gwen |
| Gwen |
| Benny |
| Diane |
+--------+
請注意該查詢只是簡單地檢索每個記錄的owner列,並且他們中的一些出現多次。為了使輸出減到最少,增加關鍵字DISTINCT檢索出每個唯一的輸出記錄:
mysql> SELECT DISTINCT owner FROM pet;
+--------+
| owner |
+--------+
| Benny |
| Diane |
| Gwen |
| Harold |
+--------+
可以使用一個WHERE子句結合行選擇與列選擇。例如,要想查詢狗和貓的出生日期,使用這個查詢:
mysql> SELECT name, species, birth FROM pet
-> WHERE species = 'dog' OR species = 'cat';
+--------+---------+------------+
| name | species | birth |
+--------+---------+------------+
| Fluffy | cat | 1993-02-04 |
| Claws | cat | 1994-03-17 |
| Buffy | dog | 1989-05-13 |
| Fang | dog | 1990-08-27 |
| Bowser | dog | 1989-08-31 |
+--------+---------+------------+
3.3.4.4. 分類行
你可能已經注意到前面的例子中結果行沒有以特定的順序顯示。然而,當行按某種方式排序時,檢查查詢輸出通常更容易。為了排序結果,使用ORDER BY子句。這裡是動物生日,按日期排序:
mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name | birth |
+----------+------------+
| Buffy | 1989-05-13 |
| Bowser | 1989-08-31 |
| Fang | 1990-08-27 |
| Fluffy | 1993-02-04 |
| Claws | 1994-03-17 |
| Slim | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+
在字元型別列上,與所有其他比較操作類似,分類功能正常情況下是以區分大小寫的方式執行的。這意味著,對於等同但大小寫不同的列,並未定義其順序。對於某一列,可以使用BINARY強制執行區分大小寫的分類功能,如:ORDER BY BINARY col_name.
預設排序是升序,最小的值在第一。要想以降序排序,在你正在排序的列名上增加DESC(降序 )關鍵字:
mysql> SELECT name, birth FROM pet ORDER BY birth DESC;
+----------+------------+
| name | birth |
+----------+------------+
| Puffball | 1999-03-30 |
| Chirpy | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim | 1996-04-29 |
| Claws | 1994-03-17 |
| Fluffy | 1993-02-04 |
| Fang | 1990-08-27 |
| Bowser | 1989-08-31 |
| Buffy | 1989-05-13 |
+----------+------------+
可以對多個列進行排序,並且可以按不同的方向對不同的列進行排序。例如,按升序對動物的種類進行排序,然後按降序根據生日對各動物種類進行排序(最年輕的動物在最前面),使用下列查詢:
mysql> SELECT name, species, birth FROM pet
-> ORDER BY species, birth DESC;
+----------+---------+------------+
| name | species | birth |
+----------+---------+------------+
| Chirpy | bird | 1998-09-11 |
| Whistler | bird | 1997-12-09 |
| Claws | cat | 1994-03-17 |
| Fluffy | cat | 1993-02-04 |
| Fang | dog | 1990-08-27 |
| Bowser | dog | 1989-08-31 |
| Buffy | dog | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim | snake | 1996-04-29 |
+----------+---------+------------+
注意DESC關鍵字僅適用於在它前面的列名(birth);不影響species列的排序順序。
3.3.4.5. 日期計算
MySQL提供了幾個函式,可以用來計算日期,例如,計算年齡或提取日期部分。
要想確定每個寵物有多大,可以計算當前日期的年和出生日期之間的差。如果當前日期的日曆年比出生日期早,則減去一年。以下查詢顯示了每個寵物的出生日期、當前日期和年齡數值的年數字。
mysql> SELECT name, birth, CURDATE(),
-> (YEAR(CURDATE())-YEAR(birth))
-> - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
-> AS age
-> FROM pet;
+----------+------------+------------+------+
| name | birth | CURDATE() | age |
+----------+------------+------------+------+
| Fluffy | 1993-02-04 | 2003-08-19 | 10 |
| Claws | 1994-03-17 | 2003-08-19 | 9 |
| Buffy | 1989-05-13 | 2003-08-19 | 14 |
| Fang | 1990-08-27 | 2003-08-19 | 12 |
| Bowser | 1989-08-31 | 2003-08-19 | 13 |
| Chirpy | 1998-09-11 | 2003-08-19 | 4 |
| Whistler | 1997-12-09 | 2003-08-19 | 5 |
| Slim | 1996-04-29 | 2003-08-19 | 7 |
| Puffball | 1999-03-30 | 2003-08-19 | 4 |
+----------+------------+------------+------+
此處,YEAR()提取日期的年部分,RIGHT()提取日期的MM-DD (日曆年)部分的最右面5個字元。比較MM-DD值的表示式部分的值一般為1或0,如果CURDATE()的年比birth的年早,則年份應減去1。整個表示式有些難懂,使用alias (age)來使輸出的列標記更有意義。
儘管查詢可行,如果以某個順序排列行,則能更容易地瀏覽結果。新增ORDER BY name子句按照名字對輸出進行排序則能夠實現。
mysql> SELECT name, birth, CURDATE(),
-> (YEAR(CURDATE())-YEAR(birth))
-> - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
-> AS age
-> FROM pet ORDER BY name;
+----------+------------+------------+------+
| name | birth | CURDATE() | age |
+----------+------------+------------+------+
| Bowser | 1989-08-31 | 2003-08-19 | 13 |
| Buffy | 1989-05-13 | 2003-08-19 | 14 |
| Chirpy | 1998-09-11 | 2003-08-19 | 4 |
| Claws | 1994-03-17 | 2003-08-19 | 9 |
| Fang | 1990-08-27 | 2003-08-19 | 12 |
| Fluffy | 1993-02-04 | 2003-08-19 | 10 |
| Puffball | 1999-03-30 | 2003-08-19 | 4 |
| Slim | 1996-04-29 | 2003-08-19 | 7 |
| Whistler | 1997-12-09 | 2003-08-19 | 5 |
+----------+------------+------------+------+
為了按age而非name排序輸出,只要再使用一個ORDER BY子句:
mysql> SELECT name, birth, CURDATE(),
-> (YEAR(CURDATE())-YEAR(birth))
-> - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
-> AS age
-> FROM pet ORDER BY age;
+----------+------------+------------+------+
| name | birth | CURDATE() | age |
+----------+------------+------------+------+
| Chirpy | 1998-09-11 | 2003-08-19 | 4 |
| Puffball | 1999-03-30 | 2003-08-19 | 4 |
| Whistler | 1997-12-09 | 2003-08-19 | 5 |
| Slim | 1996-04-29 | 2003-08-19 | 7 |
| Claws | 1994-03-17 | 2003-08-19 | 9 |
| Fluffy | 1993-02-04 | 2003-08-19 | 10 |
| Fang | 1990-08-27 | 2003-08-19 | 12 |
| Bowser | 1989-08-31 | 2003-08-19 | 13 |
| Buffy | 1989-05-13 | 2003-08-19 | 14 |
+----------+------------+------------+------+
可以使用一個類似的查詢來確定已經死亡動物的死亡年齡。你通過檢查death值是否是NULL來確定是哪些動物,然後,對於那些非NULL值的動物,需要計算出death和birth值之間的差:
mysql> SELECT name, birth, death,
-> (YEAR(death)-YEAR(birth)) - (RIGHT(death,5)<RIGHT(birth,5))
-> AS age
-> FROM pet WHERE death IS NOT NULL ORDER BY age;
+--------+------------+------------+------+
| name | birth | death | age |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 | 5 |
+--------+------------+------------+------+
查詢使用death IS NOT NULL而非death != NULL,因為NULL是特殊的值,不能使用普通比較符來比較,以後會給出解釋。參見3.3.4.6節,“NULL值操作”。
如果你想要知道哪個動物下個月過生日,怎麼辦?對於這類計算,年和天是無關的,你只需要提取birth列的月份部分。MySQL提供幾個日期部分的提取函式,例如YEAR( )、MONTH( )和DAYOFMONTH( )。在這裡MONTH()是適合的函式。為了看它怎樣工作,執行一個簡單的查詢,顯示birth和MONTH(birth)的值:
mysql> SELECT name, birth, MONTH(birth) FROM pet;
+----------+------------+--------------+
| name | birth | MONTH(birth) |
+----------+------------+--------------+
| Fluffy | 1993-02-04 | 2 |
| Claws | 1994-03-17 | 3 |
| Buffy | 1989-05-13 | 5 |
| Fang | 1990-08-27 | 8 |
| Bowser | 1989-08-31 | 8 |
| Chirpy | 1998-09-11 | 9 |
| Whistler | 1997-12-09 | 12 |
| Slim | 1996-04-29 | 4 |
| Puffball | 1999-03-30 | 3 |
+----------+------------+--------------+
找出下個月生日的動物也是容易的。假定當前月是4月,那麼月值是4,你可以找在5月出生的動物 (5月),方法是:
mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
+-------+------------+
| name | birth |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+
如果當前月份是12月,就有點複雜了。你不能只把1加到月份數(12)上並尋找在13月出生的動物,因為沒有這樣的月份。相反,你應尋找在1月出生的動物(1月) 。
你甚至可以編寫查詢,不管當前月份是什麼它都能工作。採用這種方法不必在查詢中使用一個特定的月份,DATE_ADD( )允許在一個給定的日期上加上時間間隔。如果在NOW( )值上加上一個月,然後用MONTH()提取月份,結果產生生日所在月份:
mysql> SELECT name, birth FROM pet
-> WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));
完成該任務的另一個方法是加1以得出當前月份的下一個月(在使用取模函式(MOD)後,如果月份當前值是12,則“回滾”到值0):
mysql> SELECT name, birth FROM pet
-> WHERE MONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;
注意,MONTH返回在1和12之間的一個數字,且MOD(something,12)返回在0和11之間的一個數字,因此必須在MOD( )以後加1,否則我們將從11月( 11 )跳到1月(1)。
3.3.4.6. NULL值操作
NULL值可能令人感到奇怪直到你習慣它。概念上,NULL意味著“沒有值”或“未知值”,且它被看作與眾不同的值。為了測試NULL,你不能使用算術比較 操作符例如=、<或!=。為了說明它,試試下列查詢:
mysql> SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1 <> NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
| NULL | NULL | NULL | NULL |
+----------+-----------+----------+----------+
很顯然你不能通過這些比較得到有意義的結果。相反使用IS NULL和IS NOT NULL操作符:
mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
| 0 | 1 |
+-----------+---------------+
請注意在MySQL中,0或 NULL意味著假而其它值意味著真。布林運算的預設真值是1。
對NULL的特殊處理即是在前面的章節中,為了決定哪個動物不再是活著的,使用death IS NOT NULL而不使用death != NULL的原因。
在GROUP BY中,兩個NULL值視為相同。
執行ORDER BY時,如果執行 ORDER BY ... ASC,則NULL值出現在最前面,若執行ORDER BY ... DESC,則NULL值出現在最後面。
NULL操作的常見錯誤是不能在定義為NOT NULL的列內插入0或空字串,但事實並非如此。在NULL表示"沒有數值"的地方有數值。使用IS [NOT] NULL則可以很容易地進行測試,如下所示:
mysql> SELECT 0 IS NULL, 0 IS NOT NULL, '' IS NULL, '' IS NOT NULL;
+-----------+---------------+------------+----------------+
| 0 IS NULL | 0 IS NOT NULL | '' IS NULL | '' IS NOT NULL |
+-----------+---------------+------------+----------------+
| 0 | 1 | 0 | 1 |
+-----------+---------------+------------+----------------+
因此完全可以在定義為NOT NULL的列內插入0或空字串,實際是NOT NULL。參見A.5.3節,“與NULL值有關的問題”。
3.3.4.7. 模式匹配
MySQL提供標準的SQL模式匹配,以及一種基於象Unix實用程式如vi、grep和sed的擴充套件正則表示式模式匹配的格式。
SQL模式匹配允許你使用“_”匹配任何單個字元,而“%”匹配任意數目字元(包括零字元)。在MySQL中,SQL的模式預設是忽略大小寫的。下面給出一些例子。注意使用SQL模式時,不能使用=或!=;而應使用LIKE或NOT LIKE比較操作符。
要想找出以“b”開頭的名字:
mysql> SELECT * FROM pet WHERE name LIKE 'b%';
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog &n