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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值