1 了解SQL
1.1 数据库基础
1.1.1 什么是数据库
数据库(database) 保存有组织的数据的容器(通常是一个文
件或一组文件)
数据库软件应称为DBMS(数据库管理系统)。数据库
是通过DBMS创建和操纵的容器。数据库可以是保存在硬设备
上的文件,但也可以不是。你使用的是DBMS,它替你访问数据库。
1.1.2 表
表(table) 某种特定类型数据的结构化清单。
数据库中的每个表都有一个名字,用来标识自己。此名字是唯一的,
这表示数据库中没有其他表具有相同的名字。
表名 表名的唯一性取决于多个因素,如数据库名和表名等的
结合。这表示,虽然在相同数据库中不能两次使用相同的表名,
但在不同的数据库中却可以使用相同的表名。
模式(schema) 关于数据库和表的布局及特性的信息
1.1.3 列和数据库
列(column) 表中的一个字段。所有表都是由一个或多个列组
成的。
数据类型(datatype) 所容许的数据的类型。每个表列都有相
应的数据类型,它限制(或容许)该列中存储的数据。
数据类型限制可存储在列中的数据种类(例如,防止在数值字段中
录入字符值)。数据类型还帮助正确地排序数据,并在优化磁盘使用方面起重要的作用。
1.1.4 行
表中的数据是按行存储的,所保存的每个记录存储在自己的行内。
行(row) 表中的一个记录。
1.1.5 主键
表中每一行都应该有可以唯一标识自己的一列(或一组列)
主键(primary key):一列(或一组列),其值能够唯一区分表
中每个行。
唯一标识表中每行的这个列(或这组列)称为主键。主键用来表示
一个特定的行。没有主键,更新或删除表中特定行很困难,因为没有安全的方法保证只涉及相关的行。
应该总是定义主键 :虽然并不总是都需要主键,但大多数数据
库设计人员都应保证他们创建的每个表具有一个主键,以便于
以后的数据操纵和管理。
表中的任何列都可以作为主键,只要它满足以下条件:
- 任意两行都不具有相同的主键值;
- 每个行都必须具有一个主键值(主键列不允许NULL值)。
主键通常定义在表的一列上,但这并不是必需的,也可以一起使用
多个列作为主键。在使用多列作为主键时,上述条件必须应用到构成主键的所有列,所有列值的组合必须是唯一的(但单个列的值可以不唯一)。
主键的最好习惯 除MySQL强制实施的规则外,应该坚持的
几个普遍认可的最好习惯为:
不更新主键列中的值;
不重用主键列的值;
不在主键列中使用可能会更改的值。(例如,如果使用一个
名字作为主键以标识某个供应商,当该供应商合并和更改其
名字时,必须更改这个主键。)
1.2 什么是SQL
SQL(发音为字母S-Q-L或sequel)是结构化查询语言(Structured Query Language)的缩写。SQL是一种专门用来与数据库通信的语言。
SQL有如下的优点:
-
SQL不是某个特定数据库供应商专有的语言。几乎所有重要的
DBMS都支持SQL,所以,学习此语言使你几乎能与所有数据库
打交道。
-
SQL简单易学。它的语句全都是由描述性很强的英语单词组成,
而且这些单词的数目不多。
-
SQL尽管看上去很简单,但它实际上是一种强有力的语言,灵活
使用其语言元素,可以进行非常复杂和高级的数据库操作。
2 MySQL简介
2.1 什么是MySQL
数据的所有存储、检索、管理和处理实际上是由数据库软件——DBMS(数据库管理系统)完成的。MySQL是一种DBMS,即它是一种数据库软件。
MySQL受欢迎的原因:
-
成本——MySQL是开放源代码的,一般可以免费使用(甚至可以
免费修改)。
-
性能——MySQL执行很快(非常快)。
-
可信赖——某些非常重要和声望很高的公司、站点使用MySQL,
这些公司和站点都用MySQL来处理自己的重要数据。
-
简单——MySQL很容易安装和使用。
2.1.1 客户机-服务器软件
DBMS可分为两类:一类为基于共享文件系统的DBMS,另一类为基于客户机—服务器的DBMS。前者(包括诸如Microsoft Access和FileMaker)用于桌面用途,通常不用于高端或更关键的应用。
MySQL、Oracle以及Microsoft SQL Server等数据库是基于客户机—服务器的数据库。客户机—服务器应用分为两个不同的部分。服务器部分是负责所有数据访问和处理的一个软件。这个软件运行在称为数据库服务器的计算机上
与数据文件打交道的只有服务器软件。关于数据、数据添加、删除和数据更新的所有请求都由服务器软件完成。这些请求或更改来自运行客户机软件的计算机。客户机是与用户打交道的软件。
-
服务器软件为MySQL DBMS。你可以在本地安装的副本上运行,
也可以连接到运行在你具有访问权的远程服务器上的一个副本。
-
客户机可以是MySQL提供的工具、脚本语言(如Perl)、Web应用开发语言(如ASP、ColdFusion、JSP和PHP)、程序设计语言(如C、C++、Java)等
3 使用MySQL
3.1 连接
为了连接到MySQL,需要以下信息:
- 主机名(计算机名)——如果连接到本地MySQL服务器,为localhost;
- 端口(如果使用默认端口3306之外的端口);
- 一个合法的用户名;
- 一个合法的用户名;
在连接之后,你就可以访问你的登录名能够访问的任意数据库和表
了。
3.2 选择数据库
在你最初连接到MySQL时,没有任何数据库打开供你使用。在你能执行任意数据库操作前,需要选择一个数据库。为此,可使用USE关键字。
为了使用crashcourse数据库,应该输入以下内容:use crashcourse
必须先使用USE打开数据库,才能读取其中的数据。
3.3 了解数据库和表
SHOW DATABASES;
返回可用数据库的一个列表。
SHOW TABLES;
返回当前选择的数据库内可用表的列表。
SHOW也可以用来显示表列:SHOW COLUMNS FROM customers
SHOW COLUMNS 要求给出一个表名(这个例子中的 FROM customers),它对每个字段返回一行,行中包含字段名、数据类型、是否允许NULL、键信息、默认值以及其他信息
什么是自动增量? 某些表列需要唯一值。例如,订单编号、
雇员ID或(如上面例子中所示的)顾客ID。在每个行添加到表
中时,MySQL可以自动地为每个行分配下一个可用编号,不
用在添加一行时手动分配唯一值(这样做必须记住最后一次使
用的值)。这个功能就是所谓的自动增量。如果需要它,则必
须在用CREATE语句创建表时把它作为表定义的组成部分
DESCRIBE语句 MySQL支持用DESCRIBE作为SHOW COLUMNS
FROM的一种快捷方式。换句话说,
DESCRIBE customers;
是
SHOW COLUMNS FROM customers;
的一种快捷方式。
所支持的其他SHOW语句还有:
-
SHOW STATUS
,用于显示广泛的服务器状态信息; -
SHOW CREATE DATABASE
和SHOW CREATE TABLE
,分别用来显示创建特定数据库或表的MySQL语句; -
SHOW GRANTS
,用来显示授予用户(所有用户或特定用户)的安全权限; -
SHOW ERRORS
和SHOW WARNINGS
,用来显示服务器错误或警告消息。
进一步了解SHOW 请在mysql命令行实用程序中,执行命令
HELP SHOW;
显示允许的SHOW语句。
4 检索数据
4.1 SELECT语句
SELECT语句的用途是从一个或多个表中检索信息。
为了使用SELECT检索表数据,必须至少给出两条信息——想选择什么,以及从什么地方选择。
4.2 检索单个列
select prod_name
from products
利用SELECT语句从products表中检索一个名为prod_name的列。
所需的列名在SELECT关键字之后给出,FROM关键字指出从其中检索数据的表名。
结束SQL语句: 多条SQL语句必须以分号(;)分隔。
SQL语句和大小写: 请注意,SQL语句不区分大小写,因此SELECT与select是相同的。同样,写成Select也没有关系。
使用空格:在处理SQL语句时,其中所有空格都被忽略。SQL
语句可以在一行上给出,也可以分成许多行。
4.3 检索多个列
要想从一个表中检索多个列,使用相同的SELECT语句。唯一的不同是必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。
当心逗号: 在选择多个列时,一定要在列名之间加上逗号,但最后一个列名后不加。如果在最后一个列名后加了逗号,将出现错误。
select prod_id,prod_name,prod_price
from produces;
4.4 检索所有列
除了指定所需的列外(如上所述,一个或多个列),SELECT语句还可以检索所有的列而不必逐个列出它们。这可以通过在实际列名的位置使用星号(*)通配符来达到。
select *
from products;
如果给定一个通配符(*),则返回表中所有列。列的顺序一般是列在表定义中出现的顺序。
使用通配符: 一般,除非你确实需要表中的每个列,否则最好别使用*通配符。虽然使用通配符可能会使你自己省事,不用明确列出所需列,但检索不需要的列通常会降低检索和应用程序的性能。
检索未知列: 使用通配符有一个大优点。由于不明确指定列名(因为星号检索每个列),所以能检索出名字未知的列。
4.5 检索不同的行
使用DISTINCT
关键字,顾名思义,此关键字指示MySQL只返回不同的值
select distinct vend_id
from products;
不能部分使用DISTINCT:DISTINCT关键字应用于所有列而不仅是前置它的列。如果给出SELECT DISTINCT vend_id, prod_price,除非指定的两个列都不同,否则所有行都将被检索出来。
4.6 限制结果
SELECT语句返回所有匹配的行,它们可能是指定表中的每个行。为了返回第一行或前几行,可使用LIMIT子句。
select prod_name
from products
limit 5;
此语句使用SELECT语句检索单个列。LIMIT 5指示MySQL返回不多于5行。
select prod_name
from products
limit 5,5;
LIMIT 5, 5指示MySQL返回从行5开始的5行。第一个数为开始位置,第二个数为要检索的行数。
所以,带一个值的LIMIT总是从第一行开始,给出的数为返回的行数。带两个值的LIMIT可以指定从行号为第一个值的位置开始。
行0: 检索出来的第一行为行0而不是行1。因此,LIMIT 1, 1
将检索出第二行而不是第一行。
在行数不够时: LIMIT中指定要检索的行数为检索的最大行
数。如果没有足够的行(例如,给出LIMIT 10, 5,但只有13
行),MySQL将只返回它能返回的那么多行。
MySQL 5的LIMIT语法:
LIMIT 3, 4
的含义是从行3开始的4行,MySQL 5支持LIMIT的另一种替代语法。
LIMIT 4 OFFSET 3
意为从行3开始取4行,就像LIMIT 3, 4一样。
4.7 使用完全限定的表名
也可能会使用完全限定的名字来引用列(同时使用表名和列字)
select products.prod_name
from products;
表名也可以是完全限定的,如下所示:
select products.prod_name
from crashcourse.products;
5 排序检索数据
5.1 排序数据
子句(clause): SQL语句由子句构成,有些子句是必需的,而
有的是可选的。一个子句通常由一个关键字和所提供的数据组
成。子句的例子有SELECT语句的FROM子句
为了明确地排序用SELECT语句检索出的数据,可使用ORDER BY子句。
ORDER BY子句取一个或多个列的名字,据此对输出进行排序。
select prod_name
from products
order by prod_name;
通过非选择列进行排序 :通常,ORDER BY子句中使用的列将
是为显示所选择的列。但是,实际上并不一定要这样,用非
检索的列排序数据是完全合法的。
5.2 按多个列排序
为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就
像选择多个列时所做的那样)。
下面的代码检索3个列,并按其中两个列对结果进行排序——首先按
价格,然后再按名称排序。
select prod_id,prod_price,prod_name
from products
order by prod_price,prod_name;
5.3 指定排序方向
数据排序不限于升序排序(从A到Z)。这只是默认的排序顺序,还可
以使用ORDER BY子句以降序(从Z到A)顺序排序。为了进行降序排序,必须指定DESC关键字。
select prod_id,prod_price,prod_name
from products
order by prod_price desc;
select prod_id,prod_price,prod_name
from products
order by prod_price desc,prod_name;
DESC关键字只应用到直接位于其前面的列名。在上例中,只对prod_price列指定DESC,对prod_name列不指定。因此,prod_price列以降序排序,而prod_name列(在每个价格内)仍然按标准的升序排序。
在多个列上降序排序: 如果想在多个列上进行降序排序,必须
对每个列指定DESC关键字。
区分大小写和排序顺序: 在对文本性的数据进行排序时,A与
a相同吗?a位于B之前还是位于Z之后?这些问题不是理论问
题,其答案取决于数据库如何设置。
在字典(dictionary)排序顺序中,A被视为与a相同,这是MySQL
(和大多数数据库管理系统)的默认行为。但是,许多数据库
管理员能够在需要时改变这种行为(如果你的数据库包含大量
外语字符,可能必须这样做)
使用ORDER BY和LIMIT的组合,能够找出一个列中最高或最低的值。
select prod_price
from products
order by prod_price desc
limit 1;
ORDER BY子句的位置 :在给出ORDER BY子句时,应该保证它
位于FROM子句之后。如果使用LIMIT,它必须位于ORDER BY
之后。使用子句的次序不对将产生错误消息。
6 过滤数据
6.1 使用WHERE子句
在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。
WHERE子句在表名(FROM子句)之后给出,如下所示:
select prod_name,prod_price
from products
where prod_price = 2.50;
WHERE子句的位置: 在同时使用ORDER BY和WHERE子句时,应
该让ORDER BY位于WHERE之后,否则将会产生错误
6.2 WHERE子句操作符
操作符 | 说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
between | 在指定的两个值之间 |
6.2.1 检查单个值
select prod_name,prod_price
from products
from products;
6.2.2 不匹配检查
select vend_id,prod_name
from products
where vend_id <> 1003;
或者
select vend_id,prod_name
from products
where vend_id != 1003;
6.2.3 范围值检查
为了检查某个范围的值,可使用BETWEEN操作符。
select prod_name,prod_price
from products
where prod_price between 5 and 10;
在使用BETWEEN时,必须指定两个值——所需范围的低端值和高端值。这两个值必须用AND关键字分隔。BETWEEN匹配范围中所有的值,包括指定的开始值和结束值。
6.2.4 空值检查
在一个列不包含值时,称其为包含空值NULL
NULL 无值(no value),它与字段包含0、空字符串或仅仅包含
空格不同
SELECT语句有一个特殊的WHERE子句,可用来检查具有NULL值的列。
这个WHERE子句就是IS NULL子句。其语法如下:
select prod_name
from products
where prod_price is null;
7 数据过滤
7.1 组合WHERE子句
为了进行更强的过滤控制,MySQL允许给出多个WHERE子句。这些子
句可以两种方式使用:以AND子句的方式或OR子句的方式使用。
操作符(operator) 用来联结或改变WHERE子句中的子句的关键
字。也称为逻辑操作符(logical operator)。
7.1.1 AND操作符
为了通过不止一个列进行过滤,可使用AND操作符给WHERE子句附加
条件。下面的代码给出了一个例子:
select prod_id,prod_price,price_name
from products
where vend_id = 1003 and prod_price <= 10;
7.1.2 OR操作符
OR操作符与AND操作符不同,它指示MySQL检索匹配任一条件的行。
请看如下的SELECT语句:
select prod_id,prod_price,price_name
from products
where vend_id = 1003 or vend_id = 1002;
7.1.3 计算次序
WHERE可包含任意数目的AND和OR操作符。允许两者结合以进行复杂
和高级的过滤。
SQL(像多数语言一样)在处理OR操作符前,优先处理AND操作符。
select prod_name,prod_price
from products
where (vend_id = 1003 or vend_id = 1002) and prod_price <= 10;
在WHERE子句中使用圆括号: 任何时候使用具有AND和OR操作
符的WHERE子句,都应该使用圆括号明确地分组操作符。不要
过分依赖默认计算次序,即使它确实是你想要的东西也是如
此。使用圆括号没有什么坏处,它能消除歧义。
7.2 IN操作符
圆括号在WHERE子句中还有另外一种用法。IN操作符用来指定条件范
围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清
单,全都括在圆括号中。
select prod_name,prod_price
from products
where vend_id in (1002,1003)
order by prod_name;
为什么要使用IN操作符?其优点具体如下。
-
在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
-
在使用IN时,计算的次序更容易管理(因为使用的操作符更少)
-
IN操作符一般比OR操作符清单执行更快。
-
IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建
立WHERE子句。
IN: WHERE子句中用来指定要匹配值的清单的关键字,功能与OR
相当
7.3 NOT操作符
WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所
跟的任何条件。
select prod_name,prod_price
from products
where vend_id not in (1002,1003)
order by prod_name;
MySQL中的NOT :MySQL支持使用NOT对IN、BETWEEN和
EXISTS子句取反,这与多数其他DBMS允许使用NOT对各种条件
取反有很大的差别。
8 用通配符进行过滤
8.1 LIKE操作符
通配符(wildcard) 用来匹配值的一部分的特殊字符。
**搜索模式(search pattern)**由字面值、通配符或两者组合构成的搜索条件
为在搜索子句中使用通配符,必须使用LIKE操作符。LIKE指示MySQL,
后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。
8.1.1 百分号(%)通配符
最常使用的通配符是百分号(%)。在搜索串中,%表示任何字符出现
任意次数。例如,为了找出所有以词jet起头的产品,可使用以下SELECT语句:
select prod_name,prod_price
from products
where prod_name like "jet%";
通配符可在搜索模式中任意位置使用,并且可以使用多个通配符。
下面的例子使用两个通配符,它们位于模式的两端:
select prod_name,prod_price
from products
where prod_name like "%anvil%";
通配符也可以出现在搜索模式的中间,虽然这样做不太有用。下面
的例子找出以s起头以e结尾的所有产品:
select prod_name,prod_price
from products
where prod_name like "s%e";
重要的是要注意到,除了一个或多个字符外,%还能匹配0个字符。%
代表搜索模式中给定位置的0个、1个或多个字符。
注意NULL 虽然似乎%通配符可以匹配任何东西,但有一个例
外,即NULL。即使是WHERE prod_name LIKE '%'也不能匹配
用值NULL作为产品名的行。
8.1.2 下划线(_)通配符
另一个有用的通配符是下划线(_)。下划线的用途与%一样,但下划
线只匹配单个字符而不是多个字符。
select prod_name,prod_price
from products
where prod_name like "_ton anvil";
与%能匹配0个字符不一样,_总是匹配一个字符,不能多也不能少。
8.2 使用通配符的技巧
-
不要过度使用通配符。如果其他操作符能达到相同的目的,应该
使用其他操作符。
-
在确实需要使用通配符时,除非绝对有必要,否则不要把它们用
在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起
来是最慢的。
-
仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。
9 用正则表达式进行搜索
9.1 正则表达式介绍
正则表达式是用来匹配文本的特殊的串(字符集合)。
正则表达式用正则表达式语言来建立,正则表达式语言是用来完成刚讨论的所有工作以及更多工作的一种特殊语言。与任意语言一样,正则表达式具有你必须学习的特殊的语法和指令。
9.2 使用MySQL正则表达式
正则表达式的作用是匹配文本,将一个模式(正则表达式)与一个文本串进行比较。MySQL用WHERE子句对正则表达式提供了初步的支持,允许你指定正则表达式,过滤SELECT检索出的数据。
9.2.1 基本字符匹配
下面的语句检索列prod_name包含文本1000的所有行:
select prod_name
from products
where prod_name regexp '1000'
order by prod_name;
除关键字LIKE被REGEXP替代外,这条语句看上去非常像使用LIKE的语句。它告诉MySQL:REGEXP后所跟的东西作为正则表达式(与文字正文1000匹配的一个正则表达式)处理。
select prod_name
from products
where prod_name regexp '.000'
order by prod_name;
这里使用了正则表达式.000
。.
是正则表达式语言中一个特殊的字符。它表示匹配任意一个字符,因此,1000和2000都匹配且返回。
LIKE与REGEXP: 在LIKE和REGEXP之间有一个重要的差别。请看以下两条语句:
select prod_name from products where prod_name like '1000' order by prod_name;
select prod_name from products where prod_name regexp '1000' order by prod_name;
如果执行上述两条语句,会发现第一条语句不返回数据,而第二条语句返回一行。为什么?
正如第8章所述,LIKE匹配整个列。如果被匹配的文本在列值中出现,LIKE将不会找到它,相应的行也不被返回(除非使用通配符)。而REGEXP在列值内进行匹配,如果被匹配的文本在列值中出现,REGEXP将会找到它,相应的行将被返回。这是一非常重要的差别。
那么,REGEXP能不能用来匹配整个列值(从而起与LIKE相同的作用)?答案是肯定的,使用
^
和$
定位符(anchor)即可
匹配不区分大小写 MySQL中的正则表达式匹配(自版本3.23.4后)不区分大小写(即,大写和小写都匹配)。为区分大小写,可使用
BINARY
关键字,如WHERE prod_name REGEXP BINARY 'JetPack .000'
。
9.2.2 进行OR匹配
为搜索两个串之一(或者为这个串,或者为另一个串),使用|,如下所示:
select prod_name
from products
where prod_name regexp '1000|2000'
order by prod_name;
语句中使用了正则表达式1000|2000。|为正则表达式的OR操作符。它表示匹配其中之一,因此1000和2000都匹配并返回。
使用|从功能上类似于在SELECT语句中使用OR语句,多个OR条件可并入单个正则表达式
两个以上的OR条件 可以给出两个以上的OR条件。例如,
'1000 | 2000 | 3000'
将匹配1000或2000或3000
9.2.3 匹配几个字符之一
匹配任何单一字符。但是,如果你只想匹配特定的字符,怎么办?可通过指定一组用[和]括起来的字符来完成,如下所示:
select prod_name
from products
where prod_name regexp '[123] Ton'
order by prod_name;
这里,使用了正则表达式[123] Ton
。[123]
定义一组字符,它的意思是匹配1或2或3,因此,1 ton和2 ton都匹配且返回(没有3 ton)。
[]
是另一种形式的OR语句。事实上,正则表达式[123]Ton
为[1|2|3]Ton
的缩写,也可以使用后者。但是,需要用[]
来定义OR语句查找什么。为更好地理解这一点,请看下面的例子:
select prod_name
from products
where prod_name regexp '1|2|3 Ton'
order by prod_name;
MySQL假定你的意思是’1’或’2’或’3 ton’。除非把字符|括在一个集合中,否则它将应用于整个串。
字符集合也可以被否定,即,它们将匹配除指定字符外的任何东西。为否定一个字符集,在集合的开始处放置一个^
即可。因此,尽管[123]
匹配字符1、2或3,但[^123]
却匹配除这些字符外的任何东西。
9.2.4 匹配范围
集合可用来定义要匹配的一个或多个字符。例如,下面的集合将匹配数字0到9:[0123456789]
为简化这种类型的集合,可使用-
来定义一个范围,下面的式子功能上等同于上述数字列表:[0-9]。
范围不一定只是数值的,[a-z]
匹配任意字母字符。
select prod_name
from products
where prod_name regexp '[1-5] Ton'
order by prod_name;
9.2.5 匹配特殊字符
正则表达式语言由具有特定含义的特殊字符构成。我们已经看到.
、[]
、|
和-
等,还有其他一些字符。请问,如果你需要匹配这些字符,应该怎么办呢?例如,如果要找出包含.
字符的值,怎样搜索?请看下面的例子:
select prod_name
from products
where prod_name regexp '.'
order by prod_name;
这并不是期望的输出,.匹配任意字符,因此每个行都被检索出来。
为了匹配特殊字符,必须用\\
为前导。\\-
表示查找-
,\\.
表示查找.
。
select prod_name
from products
where prod_name regexp '\\.'
order by prod_name;
这种处理就是所谓的转义(escaping),正则表达式内具有特殊意义的所有字符都必须以这种方式转义。这包括.
、|
、[]
以及迄今为止使用过的其他特殊字符。
\\
也用来引用元字符(具有特殊含义的字符)
元字符 | 说明 |
---|---|
\\f | 换页 |
\\n | 换行 |
\\r | 回车 |
\\t | 制表 |
\\v | 纵向制表 |
匹配
\
为了匹配反斜杠(\
)字符本身,需要使用\\\
。
\
或\\?
多数正则表达式实现使用单个反斜杠转义特殊字符,以便能使用这些字符本身。但MySQL要求两个反斜杠(MySQL
自己解释一个,正则表达式库解释另一个)。
9.2.6 匹配字符类
存在找出你自己经常使用的数字、所有字母字符或所有数字字母字符等的匹配。为更方便工作,可以使用预定义的字符集,称为字符类(character class)。
类 | 说明 |
---|---|
[:alnum:] | 任意字母和数字(同[a-zA-Z0-9]) |
[:alpha:] | 任意字符(同[a-zA-Z]) |
[:blank:] | 空格和制表(同[\t]) |
[:cntrl:] | ASCII控制字符(ASCII 0到31和127) |
[:digit:] | 任意数字(同[0-9]) |
[:graph:] | 与[:print:]相同,但不包括空格 |
[:lower:] | 任意小写字母(同[a-z]) |
[:print:] | 任意可打印字符 |
[:punct:] | 既不在[:alnum:]又不在[:cntrl:]中的任意字符 |
[:space:] | 包括空格在内的任意空白字符(同[\f\n\r\t\v]) |
[:upper:] | 任意大写字母(同[A-Z]) |
[:xdigit:] | 任意十六进制数字(同[a-fA-F0-9]) |
9.2.7 匹配多个实例
正则表达式重复元字符如下表:
元字符 | 说明 |
---|---|
* | 0个或多个匹配 |
+ | 1个或多个匹配(等于{1,}) |
? | 0个或1个匹配(等于{0,1}) |
{n} | 指定数目的匹配 |
{n,} | 不少于指定数目的匹配 |
{n,m} | 匹配数目的范围(m不超过255) |
select prod_name
from products
where prod_name regexp '\\([0-9] stick?\\)'
order by prod_name;
正则表达式\\([0-9] sticks?\\)
需要解说一下。\\(
匹配)
,[0-9]
匹配任意数字,sticks?
匹配stick
和sticks
(s
后的?
使s
可选,因为?
匹配它前面的任何字符的0次或1次出现),\\)
匹配)
。没有?
,匹配stick
和sticks
会非常困难。
匹配连在一起的4位数字:
select prod_name
from products
where prod_name regexp '[[:digit:]]{4}'
order by prod_name;
[:digit:]
匹配任意数字,因而它为数字的一个集合。{4}
确切地要求它前面的字符(任意数字)出现4次,所以[[:digit:]]{4}
匹配连在一起的任意4位数字。
9.2.8 定位符
为了匹配特定位置的文本,需要使用下表列出的定位符
元字符 | 说明 |
---|---|
^ | 文本的开始 |
$ | 文本的结尾 |
[[:<:]] | 词的开始 |
[[:>:]] | 词的结尾 |
select prod_name
from products
where prod_name regexp '^[0-9\\.]'
order by prod_name;
^
匹配串的开始。因此,^[0-9\\.]
只在.
或任意数字为串中第一个字符时才匹配它们
^的双重用途
^
有两种用法。在集合中(用[和]定义),用它来否定该集合,否则,用来指串的开始处。
使REGEXP起类似LIKE的作用
LIKE
和REGEXP
的不同在于,LIKE
匹配整个串而REGEXP
匹配子串。利用定位符,通过用^
开始每个表达式,用$
结束每个表达式,可以使REGEXP
的作用与LIKE
一样。
简单的正则表达式测试 可以在不使用数据库表的情况下用SELECT来测试正则表达式。REGEXP检查总是返回0(没有匹配)或1(匹配)。可以用带文字串的REGEXP来测试表达式,并试验它们。相应的语法如下:
select 'hello' regexp '[0-9];'
这个例子显然将返回0(因为文本hello中没有数字)。
10 创建计算字段
10.1 计算字段
字段(field) 基本上与列(column)的意思相同,经常互换使
用,不过数据库列一般称为列,而术语字段通常用在计算字段的
连接上。
10.2 拼接字段
拼接(concatenate) 将值联结到一起构成单个值。
在MySQL的SELECT语句中,可使用Concat()函数来拼接两个列
select concat(vend_name,'(',vend_country,')')
from vendors
order by vend_name;
Concat()拼接串,即把多个串连接起来形成一个较长的串。
Concat()需要一个或多个指定的串,各个串之间用逗号分隔。
通过删除数据右侧多余的空格来整理数据,这可以使用MySQL的RTrim()函数来完成,如下所示:
select concat(rtrim(vend_name),'(',rtrim(vend_country),')')
from vendors
order by vend_name;
RTrim()函数去掉值右边的所有空格。通过使用RTrim(),各个列都进行了整理。
Trim函数 MySQL除了支持RTrim()(正如刚才所见,它去掉
串右边的空格),还支持LTrim()(去掉串左边的空格)以及
Trim()(去掉串左右两边的空格)。
使用别名:SQL支持列别名。别名(alias)是一个字段或值的替换名。别名用AS关键字赋予。请看下面的SELECT语句:
select concat(rtrim(vend_name),'(',rtrim(vend_country),')') as vend_title
from vendors
order by vend_name