检索出来的数据并不是以存粹的随机循序显示的。如果不排序,数据一般将以它在底层底层表中出现的顺序显示。这也是数据最初添加到表中的顺序。但是,如果数据后台进行过更新或删除,则此顺序会受到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 子句描述符
在同时 使用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)
为了进行更强的过滤,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
操作符与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
可包含任意数目的AND
和OR
操作符。允许两者结合以进行复杂和高级的过滤。
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)
当AND
和OR
在一起使用的时候,AND
的优先级比OR
要高,为避免歧义,一般会在OR
的操作符加上括号。
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
操作符呢?其优点如下:
IN
操作符的语法更清楚且更直观。IN
时,计算的次序更容易管理(因为使用的操作符更少)IN
操作符一般比OR
操作符执行更快IN
的最大优点是可以包含其他SELECT
语句,使得动态地建立WHERE
子句。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
指示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)
为搜索两串之一,使用|
,
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
。