第六章 过滤数据
文章目录
- 第六章 过滤数据
- 6.1 使用where子句
- mysql> select prod_name ,prod_price -> from products-> where prod_price = 2.5;
- 6.2 where子句操作符
- 6.2.1 检查单个值
- mysql> select prod_name,prod_price-> from products-> where prod_name = 'fuses';
- mysql> select prod_name,prod_price-> from products-> where prod_price < 10;
- mysql> select prod_name,prod_price-> from products-> where prod_price < =10;
- 6.2.2 不匹配检查
- mysql> select prod_name,vend_id-> from products-> where vend_id <> 1003;
- 6.2.3 范围检查
- mysql> select prod_name ,prod_price-> from products-> where prod_price between 2 and 10;
- 6.2.4空值检查
- mysql> select prod_name-> from products-> where prod_price is null;
- mysql> select cust_id -> from customers-> where cust_email is null;
- 第七章 数据过滤
- 7.1 组合where子句
- AND操作符
- mysql> select prod_id,prod_price,prod_name-> from products -> where vend_id =1003 and prod_price <=10;
- 7.1.2 OR操作符
- mysql> select prod_name ,prod_price -> from products-> where vend_id = 1002 or vend_id = 1003;
- 7.1.3 计算次序
- mysql> select prod_name,prod_price -> from products-> where vend_id=1002 or vend_id = 1003 and prod_price >=10;
- mysql> select prod_name ,prod_price-> from products -> where (vend_id = 1002 or vend_id =1003)and prod_price >=10;
- 7.2 in操作符
- mysql> select prod_name,prod_price-> from products-> where vend_id in (1002,1003)-> order by prod_name;
- 7.3 NOT操作符
- mysql> select prod_name,prod_price-> from products-> where vend_id not in(1002,1003) -> order by prod_name;
- 第八章 用通配符进行过滤
- 8.2 通配符(wildcard)
- 搜索模式(search pattern)
- 百分号(%)通配符
- mysql> select prod_id,prod_name-> from products-> where prod_name like 'jet%';
- 下划线(_)通配符
- 8.2 使用通配符的技巧
- 第九章 正则表达式进行搜索
- 9.1 正则表达式介绍
- 9.2 使用mysql正则表达式
- 基本字符匹配
- mysql> select prod_name -> from products -> where prod_name regexp '1000' -> order by prod_name;
- 进行or匹配
- 匹配几个字符之一
- 匹配范围
- 匹配特殊字符
- 空白元字符
- 匹配字符类
- 匹配多个实例
- 定位符
- 第十章 创建计算字段
- 10.1 计算字段
- 10.2 拼接字段
- 拼接(concatenate) 将值联结到一起构成单个值。
- 使用别名
- 10.3 执行算数计算
6.1 使用where子句
数据库表一般包含大量的数据,很少需要检索表中所有行。通常只会根据特定操作或报告的需要提取表数据的子集。只检索所需数据需要 指定搜索条件(search criteria),搜索条件也称为过滤条件(filter condition)
mysql> select prod_name ,prod_price -> from products-> where prod_price = 2.5;
mysql> select prod_name ,prod_price-> from products-> where prod_price = 2.5;
+---------------+------------+
| prod_name | prod_price |
+---------------+------------+
| Carrots | 2.50 |
| TNT (1 stick) | 2.50 |
+---------------+------------+
2 rows in set (0.01 sec)#这条语句从products表中检索两个列,但不返回所有行,只返回prod_price值为2.50的行
WHERE子句的位置 在同时使用ORDER BY和WHERE子句时,应 该让ORDER BY位于WHERE之后,否则将会产生错误
6.2 where子句操作符
where
语句中的条件操作符用于比较查询对象的特定列与指定值之间的关系,常用的条件操作符包括:(from chatgpt)
=
:等于号,用于判断两个值是否相等。<>
或!=
:不等于号,用于判断两个值是否不相等。<
:小于号,用于判断一个值是否小于另一个值。>
:大于号,用于判断一个值是否大于另一个值。<=
:小于或等于号,用于判断一个值是否小于或等于另一个值。>=
:大于或等于号,用于判断一个值是否大于或等于另一个值。LIKE
:通配符,用于查找符合特定模式的字符串。BETWEEN
:用于查找某个范围内的值。IN
:用于查找一组可能的值。
6.2.1 检查单个值
mysql> select prod_name,prod_price-> from products-> where prod_name = ‘fuses’;
mysql> select prod_name,prod_price-> from products-> where prod_name = 'fuses';
+-----------+------------+
| prod_name | prod_price |
+-----------+------------+
| Fuses | 3.42 |
+-----------+------------+
1 row in set (0.00 sec)
mysql> select prod_name,prod_price-> from products-> where prod_price < 10;
mysql> select prod_name,prod_price-> from products-> where prod_price < 10;
+---------------+------------+
| prod_name | prod_price |
+---------------+------------+
| .5 ton anvil | 5.99 |
| 1 ton anvil | 9.99 |
| Carrots | 2.50 |
| Fuses | 3.42 |
| Oil can | 8.99 |
| Sling | 4.49 |
| TNT (1 stick) | 2.50 |
+---------------+------------+
7 rows in set (0.01 sec)
mysql> select prod_name,prod_price-> from products-> where prod_price < =10;
mysql> select prod_name,prod_price-> from products-> where prod_price <= 10;
+----------------+------------+
| prod_name | prod_price |
+----------------+------------+
| .5 ton anvil | 5.99 |
| 1 ton anvil | 9.99 |
| Bird seed | 10.00 |
| Carrots | 2.50 |
| Fuses | 3.42 |
| Oil can | 8.99 |
| Sling | 4.49 |
| TNT (1 stick) | 2.50 |
| TNT (5 sticks) | 10.00 |
+----------------+------------+
9 rows in set (0.01 sec)
6.2.2 不匹配检查
mysql> select prod_name,vend_id-> from products-> where vend_id <> 1003;
mysql> select prod_name,vend_id-> from products-> where vend_id <> 1003;
+--------------+---------+
| prod_name | vend_id |
+--------------+---------+
| .5 ton anvil | 1001 |
| 1 ton anvil | 1001 |
| 2 ton anvil | 1001 |
| Fuses | 1002 |
| Oil can | 1002 |
| JetPack 1000 | 1005 |
| JetPack 2000 | 1005 |
+--------------+---------+
7 rows in set (0.01 sec)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 |
| 1002 | Oil can |
| 1005 | JetPack 1000 |
| 1005 | JetPack 2000 |
+---------+--------------+
7 rows in set (0.00 sec)#由于上述已经说过不等于可以有两种写法<>或者!=上面提供的是两种写法
6.2.3 范围检查
为了检查某个范围的值,可使用BETWEEN操作符。其语法与其他WHERE子句的操作符稍有不同,因为它需要两个值,即范围的开始值和结束值。
mysql> select prod_name ,prod_price-> from products-> where prod_price between 2 and 10;
mysql> select prod_name ,prod_price-> from products-> where prod_price between 2 and 10;
+----------------+------------+
| prod_name | prod_price |
+----------------+------------+
| .5 ton anvil | 5.99 |
| 1 ton anvil | 9.99 |
| Bird seed | 10.00 |
| Carrots | 2.50 |
| Fuses | 3.42 |
| Oil can | 8.99 |
| Sling | 4.49 |
| TNT (1 stick) | 2.50 |
| TNT (5 sticks) | 10.00 |
+----------------+------------+
9 rows in set (0.01 sec)
这两个值必须用AND关键字 分隔。BETWEEN匹配范围中所有的值,包括指定的开始值和结束值
6.2.4空值检查
mysql> select prod_name-> from products-> where prod_price is null;
mysql> select prod_name-> from products-> where prod_price is null;
Empty set (0.00 sec)
mysql> select cust_id -> from customers-> where cust_email is null;
mysql> select cust_id-> from customers-> where cust_email is null;
+---------+
| cust_id |
+---------+
| 10002 |
| 10005 |
+---------+
2 rows in set (0.01 sec)
第七章 数据过滤
7.1 组合where子句
第6章中介绍的所有WHERE子句在过滤数据时使用的都是单一的条 件。为了进行更强的过滤控制,MySQL允许给出多个WHERE子句。
操作符(operator) 用来联结或改变WHERE子句中的子句的关键 字。也称为逻辑操作符(logical operator)
AND操作符
mysql> select prod_id,prod_price,prod_name-> from products -> where vend_id =1003 and prod_price <=10;
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.00 sec)
AND 用在WHERE子句中的关键字,用来指示检索满足所有给定 条件的行
7.1.2 OR操作符
mysql> select prod_name ,prod_price -> from products-> where vend_id = 1002 or vend_id = 1003;
mysql> select prod_name ,prod_price-> from products-> where vend_id = 1002 or vend_id = 1003;
+----------------+------------+
| prod_name | prod_price |
+----------------+------------+
| Fuses | 3.42 |
| Oil can | 8.99 |
| Detonator | 13.00 |
| Bird seed | 10.00 |
| Carrots | 2.50 |
| Safe | 50.00 |
| Sling | 4.49 |
| TNT (1 stick) | 2.50 |
| TNT (5 sticks) | 10.00 |
+----------------+------------+
9 rows in set (0.00 sec)
OR WHERE子句中使用的关键字,用来表示检索匹配任一给定 条件的行
7.1.3 计算次序
WHERE可包含任意数目的AND和OR操作符。允许两者结合以进行复杂 和高级的过滤。
mysql> select prod_name,prod_price -> from products-> where vend_id=1002 or vend_id = 1003 and prod_price >=10;
mysql> select prod_name,prod_price-> from products-> where vend_id=1002 or vend_id = 1003 and prod_price >=10;
+----------------+------------+
| prod_name | prod_price |
+----------------+------------+
| Fuses | 3.42 |
| Oil can | 8.99 |
| Detonator | 13.00 |
| Bird seed | 10.00 |
| Safe | 50.00 |
| TNT (5 sticks) | 10.00 |
+----------------+------------+
6 rows in set (0.00 sec)
mysql> select prod_name ,prod_price-> from products -> where (vend_id = 1002 or vend_id =1003)and prod_price >=10;
mysql> select prod_name ,prod_price-> from products-> where (vend_id = 1002 or vend_id =1003)and prod_price >=10;
+----------------+------------+
| prod_name | prod_price |
+----------------+------------+
| Detonator | 13.00 |
| Bird seed | 10.00 |
| Safe | 50.00 |
| TNT (5 sticks) | 10.00 |
+----------------+------------+
4 rows in set (0.00 sec)
7.2 in操作符
圆括号在WHERE子句中还有另外一种用法。IN操作符用来指定条件范 围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清 单,全都括在圆括号中。
mysql> select prod_name,prod_price-> from products-> where vend_id in (1002,1003)-> order by prod_name;
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.00 sec)#此SELECT语句检索供应商1002和1003制造的所有产品。IN操
#作符后跟由逗号分隔的合法值清单,整个清单必须括在圆括号中。下列表述是相同的mysql> select prod_name,prod_price-> from products-> where vend_id =1002 or vend_id = 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.00 sec)
为什么要使用IN操作符?其优点具体如下。
- 在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
- 在使用IN时,计算的次序更容易管理(因为使用的操作符更少)。
- IN操作符一般比OR操作符清单执行更快。
- IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建 立WHERE子句。
7.3 NOT操作符
WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所 跟的任何条件。
NOT WHERE子句中用来否定后跟条件的关键字。
mysql> select prod_name,prod_price-> from products-> where vend_id not in(1002,1003) -> order by prod_name;
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)#为什么使用NOT?对于简单的WHERE子句,使用NOT确实没有什么优势。但在更复杂的子句中,NOT是非常有用的。MySQL中的NOT MySQL支持使用NOT对IN、BETWEEN和EXISTS子句取反,这与多数其他DBMS允许使用NOT对各种条件取反有很大的差别
第八章 用通配符进行过滤
前面介绍的所有操作符都是针对已知值进行过滤的。不管是匹配一 个还是多个值,测试大于还是小于已知值,或者检查某个范围的值,共 同点是过滤中使用的值都是已知的。
8.2 通配符(wildcard)
用来匹配值的一部分的特殊字符。
搜索模式(search pattern)
由字面值、通配符或两者组合构 成的搜索条件
百分号(%)通配符
最常使用的通配符是百分号(%)。在搜索串中,%表示任何字符出现 任意次数。
mysql> select prod_id,prod_name-> from products-> where prod_name like ‘jet%’;
mysql> 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%'。在执行这条子句时,将检索任
#意以jet起头的词。%告诉MySQL接受jet之后的任意字符,不
#管它有多少字符
通配符可在搜索模式中任意位置使用,并且可以使用多个通配符。 下面的例子使用两个通配符,它们位于模式的两端:
mysql> select prod_id,prod_name-> from products-> where prod_name like '%anvil%';
+---------+--------------+
| prod_id | prod_name |
+---------+--------------+
| ANV01 | .5 ton anvil |
| ANV02 | 1 ton anvil |
| ANV03 | 2 ton anvil |
+---------+--------------+
3 rows in set (0.00 sec)
通配符也可以出现在搜索模式的中间,虽然这样做不太有用。下面 的例子找出以s起头以e结尾的所有产品:
mysql> select prod_id,prod_name-> from products-> where prod_name like '%e%';
+---------+--------------+
| prod_id | prod_name |
+---------+--------------+
| DTNTR | Detonator |
| FB | Bird seed |
| FU1 | Fuses |
| JP1000 | JetPack 1000 |
| JP2000 | JetPack 2000 |
| SAFE | Safe |
+---------+--------------+
6 rows in set (0.00 sec)
除了一个或多个字符外,%还能匹配0个字符。% 代表搜索模式中给定位置的0个、1个或多个字符。
注意尾空格 尾空格可能会干扰通配符匹配。例如,在保存词 anvil 时,如果它后面有一个或多个空格,则子句WHERE prod_name LIKE '%anvil’将不会匹配它们,因为在最后的l 后有多余的字符。解决这个问题的一个简单的办法是在搜索模 式最后附加一个%。一个更好的办法是使用函数(第11章将会 介绍)去掉首尾空格。
注意NULL 虽然似乎%通配符可以匹配任何东西,但有一个例 外,即NULL。即使是WHERE prod_name LIKE '%'也不能匹配 用值NULL作为产品名的行。
下划线(_)通配符
另一个有用的通配符是下划线(_)。下划线的用途与%一样,但下划 线只匹配单个字符而不是多个字符。
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> select prod_id,prod_name-> from products-> where prod_name like '% ton anvil';
+---------+--------------+
| prod_id | prod_name |
+---------+--------------+
| ANV01 | .5 ton anvil |
| ANV02 | 1 ton anvil |
| ANV03 | 2 ton anvil |
+---------+--------------+
3 rows in set (0.00 sec)
8.2 使用通配符的技巧
这种功能是有代价的:通配 符搜索的处理一般要比前面讨论的其他搜索所花时间更长。
- 不要过度使用通配符。如果其他操作符能达到相同的目的,应该 使用其他操作符。
- 在确实需要使用通配符时,除非绝对有必要,否则不要把它们用 在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起 来是最慢的。
- 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据
第九章 正则表达式进行搜索
9.1 正则表达式介绍
所有种类的程序设计语言、文本编辑器、操作系统等都支持正则表 达式。
正则表达式用正则表达式语言来建立,正则表达式语言是用来完成 刚讨论的所有工作以及更多工作的一种特殊语言。与任意语言一样,正 则表达式具有你必须学习的特殊的语法和指令。
9.2 使用mysql正则表达式
基本字符匹配
除关键字LIKE被REGEXP替代外,这条语句看上去非常像使用 LIKE的语句。它告诉MySQL:REGEXP后所跟的东西作 为正则表达式(与文字正文1000匹配的一个正则表达式)处理。正则表达式没有带来什么坏处除了可能降低性能
"regexp"是正则表达式的缩写,是一种用来匹配和处理文本的强大工具。正则表达式是一种基于字符模式的搜索和替换技术,可以帮助您在文本中找到特定模式的字符序列。它经常被用于文本编辑器、编程语言和其他计算机应用程序中,以进行字符串匹配、查找和替换操作。(from chatgpt)
mysql> select prod_name -> from products -> where prod_name regexp ‘1000’ -> order by prod_name;
mysql> select prod_name-> from products-> where prod_name regexp '1000'-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
+--------------+
1 row in set (0.02 sec)
mysql> select prod_name -> from products -> where prod_name regexp ‘1000’ -> order by prod_name;
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.01 sec)#.是正则表达式语言中一个特殊
#的字符。它表示匹配任意一个字符,因此,1000和2000都匹配且返回。这个例子也可以用LIKE和通配符来完成
mysql> select prod_name-> from products-> where prod_name like '1000'-> order by prod_name;
Empty set (0.00 sec)mysql> select prod_name-> from products-> where prod_name regexp '1000'-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
+--------------+
1 row in set (0.00 sec)
如果执行上述两条语句,会发现第一条语句不返回数据,而第 二条语句返回一行。为什么?
LIKE匹配整个列。如果被匹配的文本在列值中出现,LIKE将不会找到它,相应的行也不被返回(除非使用通配符)。而REGEXP在列值内进行匹配,如果被匹配的文本在列值中出现,REGEXP将会找到它,相应的行将被返回。这是一个非常重要的差别那么,REGEXP能不能用来匹配整个列值(从而起与LIKE相同的作用)?答案是肯定的,使用^和$定位符(anchor)即可。
进行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)语句中使用了正则表达式1000|2000。|为正则表达式的OR操作
符。它表示匹配其中之一,因此1000和2000都匹配并返回
匹配几个字符之一
匹配任何单一字符。但是,如果你只想匹配特定的字符,怎么办? 可通过指定一组用[和]括起来的字符来完成
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.01 sec)这里,使用了正则表达式[123] Ton。[123]定义一组字符,它
的意思是匹配1或2或3,因此,1 ton和2 ton都匹配且返回(没有3 ton)。
mysql> select prod_name-> from products-> where prod_name regexp '1|2|3| Ton'-> order by prod_name;
+---------------+
| prod_name |
+---------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| JetPack 1000 |
| JetPack 2000 |
| TNT (1 stick) |
+---------------+
6 rows in set (0.00 sec)这并不是期望的输出。两个要求的行被检索出来,但还检索出
了另外3行。之所以这样是由于MySQL假定你的意思是'1'或
'2'或'3 ton'。除非把字符|括在一个集合中,否则它将应用于整个串。
字符集合也可以被否定,即,它们将匹配除指定字符外的任何东西。为否定一个字符集,在集合的开始处放置一个^即可。因此,尽管[123] 匹配字符1、2或3,但[ ^1 23]却匹配除这些字符外的任何东西。
匹配范围
集合可用来定义要匹配的一个或多个字符。
为简化这种类型的集合,可使用-来定义一个范围。下面的式子功能 上等同于上述数字列表:[0-9],围不一定只是数值的,[a-z]匹配任意字母字符
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.00 sec)
匹配特殊字符
正则表达式语言由具有特定含义的特殊字符构成。我们已经看到.、[]、 |和-等,还有其他一些字符。请问,如果你需要匹配这些字符,应该怎么 办呢?
mysql> select vend_name-> from vendors-> where vend_name regexp '.'-> order by vend_name;
+----------------+
| vend_name |
+----------------+
| ACME |
| Anvils R Us |
| Furball Inc. |
| Jet Set |
| Jouets Et Ours |
| LT Supplies |
+----------------+
6 rows in set (0.01 sec)
这并不是期望的输出,.匹配任意字符,因此每个行都被检索出来
为了匹配特殊字符,必须用\\为前导。\\-表示查找-,\\.表示查找.mysql> select vend_name-> from vendors-> where vend_name regexp '\\.'-> order by vend_name;
+--------------+
| vend_name |
+--------------+
| Furball Inc. |
+--------------+
1 row in set (0.00 sec)这才是期望的输出。\\.匹配.,所以只检索出一行。这种处理
就是所谓的转义(escaping),正则表达式内具有特殊意义的所
有字符都必须以这种方式转义。这包括.、|、[]以及迄今为止使用过的
其他特殊字符。\\也用来引用元字符(具有特殊含义的字符)
空白元字符
元字符 | 说明 |
---|---|
\ \ f | 换页 |
\ \ n | 换行 |
\ \r | 回车 |
\ \t | 制表 |
\ \v | 纵向制表 |
\或\ \ ? 多数正则表达式实现使用单个反斜杠转义特殊字符, 以便能使用这些字符本身。但MySQL要求两个反斜杠(MySQL 自己解释一个,正则表达式库解释另一个)。
匹配字符类
存在找出你自己经常使用的数字、所有字母字符或所有数字字母字 符等的匹配。为更方便工作,可以使用预定义的字符集,称为字符类 (character class)。
匹配多个实例
目前为止使用的所有正则表达式都试图匹配单次出现。如果存在一 个匹配,该行被检索出来,如果不存在,检索不出任何行。但有时需要 对匹配的数目进行更强的控制。例如,你可能需要寻找所有的数,不管 数中包含多少数字,或者你可能想寻找一个单词并且还能够适应一个尾 随的s(如果存在),等等
-元字符 | -说明 |
---|---|
* | 0个或者多个匹配 |
+ | 1个或者多个匹配(等于{1,}) |
? | 0个或1个匹配(等于{0,1}) |
{n} | 指定数目的匹配 |
{n,} | 不少于指定数目的匹配 |
{n,m} | 匹配数目的范围(m不超过255) |
mysql> select prod_name-> from products-> where prod_name regexp '\\([0-9] sticks?\\)'-> order by prod_name;
+----------------+
| prod_name |
+----------------+
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
2 rows in set (0.00 sec)
正则表达式\([0-9] sticks?\)需要解说一下。\(匹配), [0-9]匹配任意数字(这个例子中为1和5),sticks?匹配stick 和sticks(s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出 现),\)匹配)。没有?,匹配stick和sticks会非常困难。
mysql> select prod_name-> from products-> where prod_name regexp '[[:digit:]]{4}'-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.00 sec)#[:digit:]匹配任意数字,因而它为数字的一个集合。{4}确切地要求它前面的字符(任意数字)出现4次,所以[[:digit:]]{4}匹配连在一起的任意4位数字#another waymysql> select prod_name-> from products-> where prod_name regexp '[0-9][0-9][0-9][0-9]'-> 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 '^[0-9\\.]'-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
+--------------+
3 rows in set (0.00 sec)
^ 匹配串的开始。因此,^ [ 0-9 \ .]只在.或任意数字为串中第 一个字符时才匹配它们。没有^,则还要多检索出4个别的行(那 些中间有数字的行)
^有两种用法。在集合中(用[和]定义),用它 来否定该集合,否则,用来指串的开始处
本章前面说过,LIKE和REGEXP 的不同在于,LIKE匹配整个串而REGEXP匹配子串。利用定位 符,通过用^开始每个表达式,用$结束每个表达式,可以使 REGEXP的作用与LIKE一样
第十章 创建计算字段
10.1 计算字段
存储在数据库表中的数据一般不是应用程序所需要的格式。下面举 几个例子。
- 如果想在一个字段中既显示公司名,又显示公司的地址,但这两 个信息一般包含在不同的表列中。
- 城市、州和邮政编码存储在不同的列中(应该这样),但邮件标签 打印程序却需要把它们作为一个恰当格式的字段检索出来。
- 列数据是大小写混合的,但报表程序需要把所有数据按大写表示 出来。
- 物品订单表存储物品的价格和数量,但不需要存储每个物品的总 价格(用价格乘以数量即可)。为打印发票,需要物品的总价格。
- 需要根据表数据进行总数、平均数计算或其他计算
字段(field) 基本上与列(column)的意思相同,经常互换使 用,不过数据库列一般称为列,而术语字段通常用在计算字段的 连接上。
10.2 拼接字段
拼接(concatenate) 将值联结到一起构成单个值。
解决办法是把两个列拼接起来。在MySQL的SELECT语句中,可使用 Concat()函数来拼接两个列。
MySQL的不同之处 多数DBMS使用+或||来实现拼接, MySQL则使用Concat()函数来实现。当把SQL语句转换成 MySQL语句时一定要把这个区别铭记在心。
mysql> select concat(vend_name,'(',vend_country,')')-> from vendors-> order by vend_name;
+----------------------------------------+
| concat(vend_name,'(',vend_country,')') |
+----------------------------------------+
| ACME(USA) |
| Anvils R Us(USA) |
| Furball Inc.(USA) |
| Jet Set(England) |
| Jouets Et Ours(France) |
| LT Supplies(USA) |
+----------------------------------------+
6 rows in set (0.01 sec)
Concat()拼接串,即把多个串连接起来形成一个较长的串。 Concat()需要一个或多个指定的串,各个串之间用逗号分隔。 上面的SELECT语句连接以下4个元素: 存储在vend_name列中的名字; 包含一个空格和一个左圆括号的串; 存储在vend_country列中的国家; 包含一个右圆括号的串。
mysql> select concat(rtrim(vend_name),' (' ,rtrim(vend_country),')')-> from vendors-> order by vend_name;
+--------------------------------------------------------+
| concat(rtrim(vend_name),' (' ,rtrim(vend_country),')') |
+--------------------------------------------------------+
| ACME (USA) |
| Anvils R Us (USA) |
| Furball Inc. (USA) |
| Jet Set (England) |
| Jouets Et Ours (France) |
| LT Supplies (USA) |
+--------------------------------------------------------+
6 rows in set (0.01 sec)RTrim()函数去掉值右边的所有空格。通过使用RTrim(),各个列都进行了整理Trim函数 MySQL除了支持RTrim()(正如刚才所见,它去掉串右边的空格),还支持LTrim()(去掉串左边的空格)以及Trim()(去掉串左右两边的空格)
使用别名
从前面的输出中可以看到,SELECT语句拼接地址字段工作得很好。 但此新计算列的名字是什么呢?实际上它没有名字,它只是一个值。如 果仅在SQL查询工具中查看一下结果,这样没有什么不好。但是,一个未 命名的列不能用于客户机应用中,因为客户机没有办法引用它。
mysql> select concat(rtrim(vend_name),',',rtrim(vend_country),')') as-> vend_title-> from vendors-> order by vend_name;
+------------------------+
| vend_title |
+------------------------+
| ACME,USA) |
| Anvils R Us,USA) |
| Furball Inc.,USA) |
| Jet Set,England) |
| Jouets Et Ours,France) |
| LT Supplies,USA) |
+------------------------+
6 rows in set (0.00 sec)
SELECT语句本身与以前使用的相同,只不过这里的语句中计算 字段之后跟了文本AS vend_title。它指示SQL创建一个包含 指定计算的名为vend_title的计算字段。从输出中可以看到,结果与以 前的相同,但现在列名为vend_title,任何客户机应用都可以按名引用 这个列,就像它是一个实际的表列一样
别名的其他用途 别名还有其他用途。常见的用途包括在实际 的表列名包含不符合规定的字符(如空格)时重新命名它,在 原来的名字含混或容易误解时扩充它,等等
导出列 别名有时也称为导出列(derived column),不管称为 什么,它们所代表的都是相同的东西
10.3 执行算数计算
计算字段的另一常见用途是对检索出的数据进行算术计算。
mysql> select prod_id,quantity,item_price-> from orderitems-> where order_num =20005;
+---------+----------+------------+
| prod_id | quantity | item_price |
+---------+----------+------------+
| ANV01 | 10 | 5.99 |
| ANV02 | 3 | 9.99 |
| TNT2 | 5 | 10.00 |
| FB | 1 | 10.00 |
+---------+----------+------------+
4 rows in set (0.01 sec)
mysql> select prod_id ,quantity,item_price,-> quantity*item_price as expanded_price-> from orderitems-> where order_num = 20005;
+---------+----------+------------+----------------+
| prod_id | quantity | item_price | expanded_price |
+---------+----------+------------+----------------+
| ANV01 | 10 | 5.99 | 59.90 |
| ANV02 | 3 | 9.99 | 29.97 |
| TNT2 | 5 | 10.00 | 50.00 |
| FB | 1 | 10.00 | 10.00 |
+---------+----------+------------+----------------+
4 rows in set (0.00 sec)输出中显示的expanded_price列为一个计算字段,此计算为quantity*item_price。
mysql可以支持基本算数操作符。圆括号可以区分有限顺序
-操作符 | -说明 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
、 | 除 |