SQL學習(排序檢索數據,過濾數據)

排序數據

檢索出來的數據並不是以存粹的隨機循序顯示的。如果不排序,數據一般將以它在底層底層表中出現的順序顯示。這也是數據最初添加到表中的順序。但是,如果數據後臺進行過更新或刪除,則此順序會受到MySQL重用回收空間的影響。因此,如果不明確控制的話,不能(也不應該)依賴排序順序。關係數據庫設計理論認爲,如果不明確規定排序順序,則不應該假定檢索出的數據的順序有意義。

mysql> SELECT prod_name FROM products ORDER BY prod_name;
+----------------+
| prod_name      |
+----------------+
| .5 ton anvil   |
| 1 ton anvil    |
| 2 ton anvil    |
| Bird seed      |
| Carrots        |
| Detonator      |
| Fuses          |
| JetPack 1000   |
| JetPack 2000   |
| Oil can        |
| Safe           |
| Sling          |
| TNT (1 stick)  |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.00 sec)

爲了明確地排序用SELECT語句檢索出的數據,可使用ORDER BY 子句。ORDER BY 子句取一個或多個列的名字,據此對輸出進行排序。

按多個列排序

mysql> SELECT prod_id,prod_price,prod_name FROM products ORDER BY prod_price,prod_name;
+---------+------------+----------------+
| prod_id | prod_price | prod_name      |
+---------+------------+----------------+
| FC      |       2.50 | Carrots        |
| TNT1    |       2.50 | TNT (1 stick)  |
| FU1     |       3.42 | Fuses          |
| SLING   |       4.49 | Sling          |
| ANV01   |       5.99 | .5 ton anvil   |
| OL1     |       8.99 | Oil can        |
| ANV02   |       9.99 | 1 ton anvil    |
| FB      |      10.00 | Bird seed      |
| TNT2    |      10.00 | TNT (5 sticks) |
| DTNTR   |      13.00 | Detonator      |
| ANV03   |      14.99 | 2 ton anvil    |
| JP1000  |      35.00 | JetPack 1000   |
| SAFE    |      50.00 | Safe           |
| JP2000  |      55.00 | JetPack 2000   |
+---------+------------+----------------+
14 rows in set (0.00 sec)

在多個列排序時,排序完全按所規定的順序進行。對於上面的列子中,僅在多個列具有相同的prod_price值時纔對產品按prod_name進行排序。如果prod_price列中所有的值都是唯一的,則不會按prod_name排序。

指定排序方向

數據排序不限於升序排序。這只是默認的排序順序,還可以使用ORDER BY子句以降序順序排序。爲了進行降序排序,必須指定DESC關鍵字。

mysql> SELECT prod_id,prod_price,prod_name FROM products ORDER BY prod_price DESC, prod_name;
+---------+------------+----------------+
| prod_id | prod_price | prod_name      |
+---------+------------+----------------+
| JP2000  |      55.00 | JetPack 2000   |
| SAFE    |      50.00 | Safe           |
| JP1000  |      35.00 | JetPack 1000   |
| ANV03   |      14.99 | 2 ton anvil    |
| DTNTR   |      13.00 | Detonator      |
| FB      |      10.00 | Bird seed      |
| TNT2    |      10.00 | TNT (5 sticks) |
| ANV02   |       9.99 | 1 ton anvil    |
| OL1     |       8.99 | Oil can        |
| ANV01   |       5.99 | .5 ton anvil   |
| SLING   |       4.49 | Sling          |
| FU1     |       3.42 | Fuses          |
| FC      |       2.50 | Carrots        |
| TNT1    |       2.50 | TNT (1 stick)  |
+---------+------------+----------------+
14 rows in set (0.00 sec)

DESC關鍵字只應用到直接位於其前面的列名。在上例中,只對prod_price列指定DESC,對prod_name列不指定。因此,prod_price列以降序排序,而prod_name列仍然按標準的升序排序。

過濾數據

數據庫表中一般包含大量的數據,很少需要檢索表中所有行。通常只會根據特定操作或報告的需要提取數據的子集。只檢索數據需要指定搜索條件。搜索條件也被稱爲過濾條件。
在SELECT 語句中,數據根據WHERE子句中指定的搜索條件進行過濾。WHERE子句在表名之後給出。

mysql> SELECT prod_id,prod_price FROM products WHERE prod_price=2.5;
+---------+------------+
| prod_id | prod_price |
+---------+------------+
| FC      |       2.50 |
| TNT1    |       2.50 |
+---------+------------+
2 rows in set (0.00 sec)

WHERE 子句描述符
WHERE 子句描述符
在同時 使用ORDER BY 和 WHERE子句時,應該讓ORDER BY 位於WHERE之後。

檢查單個值

mysql> SELECT  prod_price, prod_name FROM products WHERE  prod_name = 'fuses';
+------------+-----------+
| prod_price | prod_name |
+------------+-----------+
|       3.42 | Fuses     |
+------------+-----------+
1 row in set (0.00 sec)

檢查WHERE prod_name='fuses’語句,它返回prod_name的值爲Fuses的一行。MySQL在執行匹配時默認不區分大小寫,所以fuses與Fuses匹配。

不匹配檢查

如果將值與串類型的列進行比較,則需要限定引號。用來與數值列進項比較的值不用引號。

mysql> SELECT vend_id, prod_name FROM products WHERE vend_id <> 1003;
+---------+--------------+
| vend_id | prod_name    |
+---------+--------------+
|    1001 | .5 ton anvil |
|    1001 | 1 ton anvil  |
|    1001 | 2 ton anvil  |
|    1002 | Fuses        |
|    1005 | JetPack 1000 |
|    1005 | JetPack 2000 |
|    1002 | Oil can      |
+---------+--------------+
7 rows in set (0.01 sec)

上面個的<>也可以寫爲!=

檢查多個值

SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id =1003 AND prod_price <=10;

範圍值檢查

爲了檢查某個範圍的值,可使用BETWEEN操作符。其語言與其它WHERE子句的操作符稍有不同,因爲它需要兩個值,即範圍的開始值和結束值。

mysql> SELECT prod_price, prod_name FROM products WHERE prod_price BETWEEN 50 AND 100;
+------------+--------------+
| prod_price | prod_name    |
+------------+--------------+
|      55.00 | JetPack 2000 |
|      50.00 | Safe         |
+------------+--------------+
2 rows in set (0.00 sec)

在使用BETWEEN時,必須指定兩個值——所需範圍的低端值和高端值。這兩個值必須用AND關鍵字分隔。BETWEEN匹配範圍中所有的值,包括指定的開始值和結束值。

空值檢查

在一個列不包含值時,稱其爲包含空值NULL。
SELECT語句有一個特殊的WHERE子句,可用來檢查具有NULL值得列。這個子句就是IS NULL子句。

mysql> SELECT cust_id FROM customers WHERE cust_email IS NULL;
+---------+
| cust_id |
+---------+
|   10002 |
|   10005 |
+---------+
2 rows in set (0.01 sec)

數據過濾

AND操作符

爲了進行更強的過濾,MySQL允許給出多個WHERE子句。這些子句可以兩種方式使用:以AND子句的方式或OR子句的方式使用。

mysql> SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id =1003 AND prod_price <=10;
+---------+------------+----------------+
| prod_id | prod_price | prod_name      |
+---------+------------+----------------+
| FB      |      10.00 | Bird seed      |
| FC      |       2.50 | Carrots        |
| SLING   |       4.49 | Sling          |
| TNT1    |       2.50 | TNT (1 stick)  |
| TNT2    |      10.00 | TNT (5 sticks) |
+---------+------------+----------------+
5 rows in set (0.01 sec)

上述例子中使用了只包含一個關鍵字AND的語句,把兩個過濾條件組合在一起。駭客已添加多個過濾條件,每添加一條就要使用一個AND

OR操作符

OR操作符與AND操作符不同,它指示MySQL檢索匹配任一條件的行。

mysql> SELECT  prod_price, prod_name,vend_id FROM products WHERE vend_id =1003 OR vend_id =1002;
+------------+----------------+---------+
| prod_price | prod_name      | vend_id |
+------------+----------------+---------+
|      13.00 | Detonator      |    1003 |
|      10.00 | Bird seed      |    1003 |
|       2.50 | Carrots        |    1003 |
|       3.42 | Fuses          |    1002 |
|       8.99 | Oil can        |    1002 |
|      50.00 | Safe           |    1003 |
|       4.49 | Sling          |    1003 |
|       2.50 | TNT (1 stick)  |    1003 |
|      10.00 | TNT (5 sticks) |    1003 |
+------------+----------------+---------+
9 rows in set (0.00 sec)

計算次序

WHERE可包含任意數目的ANDOR操作符。允許兩者結合以進行復雜和高級的過濾。

mysql> SELECT  prod_price, prod_name FROM products WHERE (vend_id=1003 OR vend_id =1002) AND prod_price >= 10;
+------------+----------------+
| prod_price | prod_name      |
+------------+----------------+
|      13.00 | Detonator      |
|      10.00 | Bird seed      |
|      50.00 | Safe           |
|      10.00 | TNT (5 sticks) |
+------------+----------------+
4 rows in set (0.00 sec)

ANDOR在一起使用的時候,AND的優先級比OR要高,爲避免歧義,一般會在OR的操作符加上括號。

IN操作符

IN 操作符用來指定條件範圍,範圍中的每個條件都進行匹配。IN取合法值的由逗號分隔的清單,全部包括在圓括號中。

mysql> SELECT prod_name, prod_price FROM products WHERE vend_id IN (1002,1003) ORDER BY prod_name;
+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| Bird seed      |      10.00 |
| Carrots        |       2.50 |
| Detonator      |      13.00 |
| Fuses          |       3.42 |
| Oil can        |       8.99 |
| Safe           |      50.00 |
| Sling          |       4.49 |
| TNT (1 stick)  |       2.50 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+
9 rows in set (0.01 sec)

IN操作符完成與OR相同的功能,爲什麼要使用IN操作符呢?其優點如下:

  1. 在使用長的合法選項清單時,IN操作符的語法更清楚且更直觀。
  2. 在使用IN時,計算的次序更容易管理(因爲使用的操作符更少)
  3. IN操作符一般比OR操作符執行更快
  4. IN的最大優點是可以包含其他SELECT語句,使得動態地建立WHERE子句。

NOT操作符

WHERE子句中的NOT只有一個功能,那就是否定它之後所跟的任何條件。

mysql> SELECT prod_name, prod_price FROM products WHERE vend_id NOT IN (1002,1003) ORDER BY prod_name;
+--------------+------------+
| prod_name    | prod_price |
+--------------+------------+
| .5 ton anvil |       5.99 |
| 1 ton anvil  |       9.99 |
| 2 ton anvil  |      14.99 |
| JetPack 1000 |      35.00 |
| JetPack 2000 |      55.00 |
+--------------+------------+
5 rows in set (0.00 sec)

用通配符進行過濾

LIKE操作符

通配符:用來匹配值的一部分的特殊字符
搜索模式:由字面值、通配符、或兩者組合構成的搜索條件。
爲了在子句中使用通配符,必須使用LIKE操作符。LIKE指示MySQL,後跟的搜索模式利用通配符匹配而不是直接相等匹配進行比較。

百分號通配符

最常使用的通配符是百分號(%)。在搜索串中,%表示任何字符出現任意次數。例如,爲了找出所有以詞jet起頭的產品,可使用SELECT語句。

ysql> SELECT prod_id,prod_name FROM products WHERE prod_name LIKE 'jet%';
+---------+--------------+
| prod_id | prod_name    |
+---------+--------------+
| JP1000  | JetPack 1000 |
| JP2000  | JetPack 2000 |
+---------+--------------+
2 rows in set (0.00 sec)

在執行這條語句時,將檢索任意以jet起頭的詞。

下劃線通配符

下劃線(_)的用途與%一樣,但下劃線只匹配單個字符而不是多個字符。

mysql> SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '_ TON ANVIL';
+---------+-------------+
| prod_id | prod_name   |
+---------+-------------+
| ANV02   | 1 ton anvil |
| ANV03   | 2 ton anvil |
+---------+-------------+
2 rows in set (0.00 sec)

使用通配符的技巧

MySQL的通配符很有用。但這種功能是有代價的:通配符搜索的處理一般要比前面討論的其他搜索所花時間更長。

  • 不要過度的使用通配符。
  • 在確定使用通配符時,除非絕對必要,否則不要把他們用在搜索模式的開始處,這會導致搜索起來速度最慢。
  • 仔細注意通配符的位置。

用正則表達式進行搜索

基本字符匹配

下面的語句檢索列prod_name包含文本含有000所有的行

mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '.000' ORDER BY prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.00 sec)

進行OR匹配

爲搜索兩串之一,使用|

mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '1000|2000' ORDER BY prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.00 sec)

匹配幾個字符之一

如果你想匹配特定的字符,可通過指定一組[]括起來的字符完成

mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '[123] Ton' ORDER BY prod_name;
+-------------+
| prod_name   |
+-------------+
| 1 ton anvil |
| 2 ton anvil |
+-------------+
2 rows in set (0.02 sec)

匹配範圍

集合可以用來定義要匹配的一個或多個字符。

mysql> SELECT prod_name FROM products WHERE prod_name REGEXP '[1-5] Ton' ORDER BY prod_name;
+--------------+
| prod_name    |
+--------------+
| .5 ton anvil |
| 1 ton anvil  |
| 2 ton anvil  |
+--------------+
3 rows in set (0.01 sec)

這裏使用正則表達式[1-5] Ton[1-5]定義了一個範圍,這個表達式意思是匹配1到5,因此返回3個匹配行。由於5 ton匹配,所以返回.5 ton

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章