只检索所需数据需要指定搜索条件(search criteria),搜索条件也称为过滤条件(filter condition)。
SQL过滤与应用过滤 数据也可以在应用层过滤。为此目的,SQL的SELECT语句为客户机应用检索出超过实际所需的数据,然后客户机代码对返回数据进行循环,以提取出需要的行。
通常,这种实现并不令人满意。因此,对数据库进行了优化,以便快速有效地对数据进行过滤。让客户机应用(或开发语言)处理数据库的工作将会极大地影响应用的性能,并且使所创建的应用完全不具备可伸缩性。此外,如果在客户机上过滤数据,服务器不得不通过网络发送多余的数据,这将导致网络带宽的浪费。
MySQL支持表6-1列出的所有条件操作符。
检查WHERE prod_name=‘fuses’语句,它返回prod_name的值为Fuses的一行。MySQL在执行匹配时默认不区分大小写,所以fuses与Fuses匹配。
何时使用引号 如果仔细观察上述WHERE子句中使用的条件,会看到有的值括在单引号内(如前面使用的'fuses'),而有的值未括起来。单引号用来限定字符串。如果将值与串类型的列进行比较,则需要限定引号。用来与数值列进行比较的值不用引号。
BETWEEN匹配范围中所有的值,包括指定的开始值和结束值。
操作符(operator) 用来联结或改变WHERE子句中的子句的关键字。也称为逻辑操作符(logical operator)。
在WHERE子句中使用圆括号 任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确地分组操作符。不要过分依赖默认计算次序,即使它确实是你想要的东西也是如此。使用圆括号没有什么坏处,它能消除歧义。
为什么要使用IN操作符?其优点具体如下。
IN WHERE子句中用来指定要匹配值的清单的关键字,功能与OR相当。
WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。
not in
MySQL中的NOT MySQL支持使用NOT 对IN 、BETWEEN 和EXISTS子句取反,这与多数其他DBMS允许使用NOT对各种条件取反有很大的差别。
通配符(wildcard) 用来匹配值的一部分的特殊字符。
搜索模式(search pattern)由字面值、通配符或两者组合构成的搜索条件。
另一个有用的通配符是下划线(_)。下划线的用途与%一样,但下划线只匹配单个字符而不是多个字符。
使用通配符的技巧
正如所见,MySQL的通配符很有用。但这种功能是有代价的:通配符搜索的处理一般要比前面讨论的其他搜索所花时间更长。这里给出一些使用通配符要记住的技巧。
仅为正则表达式语言的一个子集 如果你熟悉正则表达式,需要注意:MySQL仅支持多数正则表达式实现的一个很小的子集。本章介绍MySQL支持的大多数内容。
检索列prod_name包含文本1000的所有行:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000';
除关键字LIKE被REGEXP替代外,这条语句看上去非常像使用LIKE的语句(第8章)。它告诉MySQL:REGEXP后所跟的东西作为正则表达式(与文字正文1000匹配的一个正则表达式)处理。
为什么要费力地使用正则表达式?在刚才的例子中,正则表达式确实没有带来太多好处(可能还会降低性能),不过,请考虑下面的例子:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '.000';
这里使用了正则表达式.000。.是正则表达式语言中一个特殊的字符。它表示匹配任意一个字符,因此,1000和2000都匹配且返回。
LIKE与REGEXP 在LIKE和REGEXP之间有一个重要的差别。请看以下两条语句:
SELECT prod_name
FROM products
WHERE prod_name LIKE '1000';
SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000';
如果执行上述两条语句,会发现第一条语句不返回数据,而第二条语句返回一行。为什么?
正如第8章所述,LIKE匹配整个列。如果被匹配的文本在列值中出现,LIKE将不会找到它,相应的行也不被返回(除非使用通配符)。而REGEXP在列值内进行匹配,如果被匹配的文本在列值中出现,REGEXP将会找到它,相应的行将被返回。这是一个非常重要的差别。
那么,REGEXP能不能用来匹配整个列值(从而起与LIKE相同的作用)?答案是肯定的,使用^和$定位符(anchor)即可,本章后面介绍。
匹配不区分大小写 MySQL中的正则表达式匹配(自版本3.23.4后)不区分大小写(即,大写和小写都匹配)。为区分大小写,可使用BINARY关键字,如WHERE prod_name REGEXPBINARY 'JetPack .000'。
为搜索两个串之一(或者为这个串,或者为另一个串),使用|,如下所示:
SELECT prod_name
FROM products
WHERE prod_name LIKE '1000|2000';
匹配任何单一字符。但是,如果你只想匹配特定的字符,怎么办?可通过指定一组用[和]括起来的字符来完成,如下所示:
SELECT prod_name
FROM products
WHERE prod_name LIKE '[123]Ton';
这里,使用了正则表达式[123] Ton。[123]定义一组字符,它的意思是匹配1或2或3,因此,1 ton和2 ton都匹配且返回(没有3 ton)。
知道了正则表达式这么一个东西的存在,先不错深入研究。等遇到了之后再回来找吧。
在第8章中曾提到通过删除数据右侧多余的空格来整理数据,这可以使用MySQL的RTrim()函数来完成,如下所示:
SELECT CONCAT(RTrim(vend_name),'(', vend_country, ')')
FROM vendors
ORDER BY vend_name;
RTrim()函数去掉值右边的所有空格。通过使用RTrim(),各个列都进行了整理。
Trim函数 MySQL除了支持RTrim()(正如刚才所见,它去掉串右边的空格),还支持LTrim()(去掉串左边的空格)以及Trim()(去掉串左右两边的空格)。
别名的其他用途 别名还有其他用途。常见的用途包括在实际的表列名包含不符合规定的字符(如空格)时重新命名它,在原来的名字含混或容易误解时扩充它,等等。
导出列 别名有时也称为导出列(derived column),不管称为什么,它们所代表的都是相同的东西。