除非最終檢索它們並利用它們來做點事情,否則將記錄放入數據庫沒什麼好處。這就是 SELECT 語句的用途,即幫助取出數據。SELECT 大概是 SQL 語言中最常用的語句,而且怎樣使用它也最為講究;用它來選擇記錄可能相當復雜,可能會涉及許多表中列之間的比較。本節介紹Select語句關於查詢的最基本功能。
SELECT 語句的語法如下:
SELECT selection_list 選擇哪些列
FROM table_list 從何處選擇行
WHERE primary_constraint 行必須滿足什麼條件
GROUP BY grouping_columns 怎樣對結果分組
HAVING secondary_constraint 行必須滿足的第二條件
ORDER BY sorting_columns 怎樣對結果排序
LIMIT count 結果限定
注意:所有使用的關鍵詞必須精確地以上面的順序給出。例如,一個HAVING子句必須跟在GROUP BY子句之後和ORDER BY子句之前。
除了詞“SELECT”和說明希望檢索什麼的 column_list 部分外,語法中的每樣東西都是可選的。有的數據庫還需要 FROM 子句。MySQL 有所不同,它允許對表達式求值而不引用任何表。
普通查詢
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 |
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Fang | Benny | dog | m | 1990-08-27 | NULL |
| Bowser | Diane | dog | m | 1990-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
| Slim | Benny | snake | m | 1996-04-29 | NULL |
| Puffball | Diane | hamster | f | 1999-03-30 | NULL |
+----------+--------+---------+------+------------+------------+
查詢特定行:
你能從你的表中只選擇特定的行。例如,如果你想要驗證你對Bowser的出生日期所做的改變,像這樣精選Bowser的記錄:
MySQL> SELECT * FROM pet WHERE name = "Bowser";
其結果為:
+--------+-------+---------+------+------------+------------+
| name | owner | specIEs | sex | birth | death |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog | m | 1990-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+
你可以對照前一個例子來驗證。
查詢特定列
如果你不想要看到你的表的整個行,就命名你感興趣的列,用逗號分開。例如,如果你想要知道你的動物什麼時候出生的,精選name和birth列:
MySQL> SELECT name, birth FROM pet where owner="Gwen";
其結果為:
+----------+------------+
| name | birth |
+----------+------------+
| Claws | 1994-03-17 |
| Chirpy | 1998-09-11 |
| Whistler | 1997-12-09 |
+----------+------------+
進行表達式計算
前面的多數查詢通過從表中檢索值已經產生了輸出結果。MySQL 還允許作為一個公式的結果來計算輸出列的值。表達式可以簡單也可以復雜。下面的查詢求一個簡單表達式的值(常量)以及一個涉及幾個算術運算符和兩個函數調用的較復雜的表達式的值。例如,計算Browser生活的天數:
MySQL> SELECT death-birth FROM pet WHERE name="Bowser";
其結果是:
+-------------+
| death-birth |
+-------------+
| 49898 |
+-------------+
由於MySQL允許對表達式求值而不引用任何表。所以也可以這樣使用:
MySQL>select (2+3*4.5)/2.5;
其結果為:
+---------------+
| (2+3*4.5)/2.5 |
+---------------+
| 6.200 |
+---------------+
條件查詢
不必每次查詢都返回所有的行記錄,你能從你的表中只選擇特定的行。為此你需要使用WHERE或者HAVING從句。HAVING從句與WHERE從句的區別是,HAVING表達的是第二條件,在與其他從句配合使用,顯然不能在WHERE子句中的項目使用HAVING。因此本小節緊介紹WHERE從句的使用,HAVING從句的使用方法類似。另外WHERE從句也可以實現HAVING從句的絕大部分功能。
為了限制 SELECT 語句檢索出來的記錄集,可使用 WHERE 子句,它給出選擇行的條件。可通過查找滿足各種條件的列值來選擇行。
WHERE 子句中的表達式可使用表1 中的算術運算符、表2 的比較運算符和表3 的邏輯運算符。還可以使用圓括號將一個表達式分成幾個部分。可使用常量、表列和函數來完成運算。在本教程的查詢中,我們有時使用幾個 MySQL 函數,但是 MySQL 的函數遠不止這裡給出的這些。請參閱附錄 一,那裡給出了所有MySQL 函數的清單。
表1 算術運算符
運算符
說明
運算符
說明
+
-
加
減
*
/
乘
除
表2 比較運算符
運算符
說明
運算符
說明
<
<=
=
小於
小於或等於
等於
!= 或 <>
>=
>
不等於
大於或等於
大於
表3 邏輯運算符
運算符
說明
NOT或 !
OR 或 ||
AND或 &&
邏輯非
邏輯或
邏輯與
例如,如果你想要驗證你對Bowser的出生日期所做的改變,像這樣精選Bowser的記錄:
MySQL> SELECT * FROM pet WHERE name = "Bowser";
+--------+-------+---------+------+------------+------------+
| name | owner | specIEs | sex | birth | death |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog | m | 1990-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+
輸出證實出生年份現在正確記錄為1990,而不是1909。
字符串比較通常是大小些無關的,因此你可以指定名字為"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可以混用。如果你這樣做,使用括號指明條件應該如何被分組是一個好主意:
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 |
+-------+--------+---------+------+------------+-------+
查詢排序
使用ORDER BY子句對查詢返回的結果按一列或多列排序。ORDER BY子句的語法格式為:
ORDER BY column_name [ASC|DESC] [,…]
其中ASC表示升序,為默認值,DESC為降序。ORDER BY不能按text、text和image數據類型進行排 序。另外,可以根據表達式進行排序。
例如,這裡是動物生日,按日期排序:
MySQL> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name | birth |
+----------+------------+
| Buffy | 1989-05-13 |
| Fang | 1990-08-27 |
| Bowser | 1990-08-31 |
| Fluffy | 1993-02-04 |
| Claws | 1994-03-17 |
| Slim | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+
為了以逆序排序,增加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 |
| Bowser | 1990-08-31 |
| Fang | 1990-08-27 |
| 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 |
| Bowser | dog | 1990-08-31 |
| Fang | dog | 1990-08-27 |
| Buffy | dog | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim | snake | 1996-04-29 |
+----------+---------+------------+
注意DESC關鍵詞僅適用於緊跟在它之前的列名字(birth);species值仍然以升序被排序。注意,輸出首先按照species排序,然後具有相同specIEs的寵物再按照birth降序排列。
查詢分組與行計數
GROUP BY 從句根據所給的列名返回分組的查詢結果,可用於查詢具有相同值的列。其語法為:
GROUP BY col_name,….
你可以為多個列分組。
例如:
MySQL>SELECT * FROM pet GROUP BY specIEs;
+----------+--------+---------+------+------------+-------+
| name | owner | specIEs | sex | birth | death |
+----------+--------+---------+------+------------+-------+
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Puffball | Diane | hamster | f | 1999-03-30 | NULL |
| Slim | Benny | snake | m | 1996-04-29 | NULL |
+----------+--------+---------+------+------------+-------+
由以上結果可以看出:
查詢顯示結果時,被分組的列如果有重復的值,只返回靠前的記錄,並且返回的記錄集是排序的。這並不是一個很好的結果。僅僅使用GROUP BY從句並沒有什麼意義,該從句的真正作用在於與各種組合函數配合,用於行計數。
1、COUNT()函數計數非NULL結果的數目。
你可以這樣計算表中記錄行的數目:
MySQL> select count(*) from pet;
+----------+
| count(*) |
+----------+
| 9 |
+----------+
計算sex為非空的記錄數目:
MySQL> select count(sex) from pet;
+------------+
| count(sex) |
+------------+
| 8 |
+------------+
現在配合GROUP BY 從句使用。
例如:要知道每個主人有多少寵物
MySQL> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner | COUNT(*) |
+--------+----------+
| Benny | 2 |
| Diane | 2 |
| Gwen | 3 |
| Harold | 2 |
+--------+----------+
又如,每種寵物的個數:
MySQL> SELECT species,count(*) FROM pet GROUP BY specIEs;
+---------+----------+
| specIEs | count(*) |
+---------+----------+
| bird | 2 |
| cat | 2 |
| dog | 3 |
| hamster | 1 |
| snake | 1 |
+---------+----------+
如果你除了計數還返回一個列的值,那麼必須使用GROU BY語句,否則無法計算記錄。例如上例,使用GROUP BY對每個owner分組所有記錄,沒有它,你得到的一切是一條錯誤消息:
MySQL> SELECT owner, COUNT(owner) FROM pet;
ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
with no GROUP columns is illegal if there is no GROUP BY clause
也可以根據多個列分組,例如:
按種類和性別組合的動物數量:
MySQL> SELECT species, sex, COUNT(*) FROM pet GROUP BY specIEs, sex;
+---------+------+----------+
| specIEs | sex | COUNT(*) |
+---------+------+----------+
| bird | NULL | 1 |
| bird | f | 1 |
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
| hamster | f | 1 |
| snake | m | 1 |
+---------+------+----------+
查詢多個表
查詢多個表,FROM子句列出表名,並用逗號分隔,因為查詢需要從他們兩個拉出信息。
當組合(聯結-join)來自多個表的信息時,你需要指定在一個表中的記錄怎樣能匹配其它表的記錄。這很簡單,因為它們都有一個name列。查詢使用WHERE子句基於name值來匹配2個表中的記錄。
因為name列出現在兩個表中,當引用列時,你一定要指定哪個表。這通過把表名附在列名前做到。
現在有一個event表:
MySQL>select * from event;
+----------+------------+----------+-----------------------------+
| name | date | type | remark |
+----------+------------+----------+-----------------------------+
| Fluffy | 1995-05-15 | litter | 4 kittens, 3 female, 1 male |
| Buffy | 1993-06-23 | litter | 5 puppIEs, 2 female, 3 male |
| Buffy | 1994-06-19 | litter | 3 puppIEs, 3 female |
| Chirpy | 1999-03-21 | vet | needed beak straightened |
| Slim | 1997-08-03 | vet | broken rib |
| Bowser | 1991-10-12 | kennel | NULL |
| Fang | 1991-10-12 | kennel | NULL |
| Fang | 1998-08-28 | birthday | Gave him a new chew toy |
| Claws | 1998-03-17 | birthday | Gave him a new flea collar |
| Whistler | 1998-12-09 | birthday | First birthday |
+----------+------------+----------+-----------------------------+
當他們有了一窩小動物時,假定你想要找出每只寵物的年齡。 event表指出何時發生,但是為了計算母親的年齡,你需要她的出生日期。既然它被存儲在pet表中,為了查詢你需要兩張表:
MySQL> SELECT pet.name, (TO_DAYS(date) - TO_DAYS(birth))/365 AS age, remark
-> FROM pet, event
-> WHERE pet.name = event.name AND type = "litter";
+--------+------+-----------------------------+
| name | age | remark |
+--------+------+-----------------------------+
| Fluffy | 2.27 | 4 kittens, 3 female, 1 male |
| Buffy | 4.12 | 5 puppIEs, 2 female, 3 male |
| Buffy | 5.10 | 3 puppIEs, 3 female |
+--------+------+-----------------------------+
同樣方法也可用於同一張表中,你不必有2個不同的表來執行一個聯結。如果你想要將一個表的記錄與同一個表的其他記錄進行比較,聯結一個表到自身有時是有用的。例如,為了在你的寵物之中繁殖配偶,你可以用pet聯結自身來進行相似種類的雄雌配對:
MySQL> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.specIEs
-> FROM pet AS p1, pet AS p2
-> WHERE p1.species = p2.specIEs AND p1.sex = "f" AND p2.sex = "m";
+--------+------+--------+------+---------+
| name | sex | name | sex | specIEs |
+--------+------+--------+------+---------+
| Fluffy | f | Claws | m | cat |
| Buffy | f | Fang | m | dog |
| Buffy | f | Bowser | m | dog |
+--------+------+--------+------+---------+
在這個查詢中,我們為表名指定別名以便能引用列並且使得每一個列引用關聯於哪個表實例更直觀。
總結
本文總結了SELECT語句檢索記錄的簡單使用方法。其中涉及到的內容主要包括以下一些內容:
1、WHERE從句的用法
2、GROUP BY從句的用法
3、ORDER BY從句的用法
4、連接多個表的簡單介紹