前言
MySQL数据库表内存储着上千万条数据,其中只有一小部分会是我们需要的。将这部分需要的数据从表中检索出来,我们需要借助数据过滤。
可以看出,数据过滤可以算我们日常开发中最多接触的部分。
这篇文章是一些我学习上的总结。
内容
WHERE子句
WHERE子句用于在SELECT语句中定义过滤条件。这个过滤条件会被执行于每一行数据,根据过滤条件返回的布尔值TRUE或FALSE决定行数据是否被检索返回。没有定义WHERE子句的SELECT语句会检索返回表内的所有数据。
WHERE子句的使用格式如下:
# 过滤条件
SELECT * FROM [table_name] WHERE [where_condition];
上面的使用格式中,搜索条件where_condition可以由MySQL支持的函数和操作符组成。
条件操作符
WHERE子句的条件操作符用于构建过滤条件项,条件操作符包括如下:
| 操作符 | 说明 | 操作符 | 说明 |
|---|---|---|---|
= | 等于 | <> | 不等于 |
!= | 不等于 | < | 小于 |
<= | 小于等于 | > | 大于 |
>= | 大于等于 | BETWEEN | 在指定的两个值之间 |
使用这些条件操作符,我们就可以对结果集进行过滤检索。
# 匹配检查
SELECT * FROM [table_name] WHERE [column_name] = [column_value];
# 不匹配检查
SELECT * FROM [table_name] WHERE [column_name] != [column_value];
# 范围检查
SELECT * FROM [table_name] WHERE [column_name] BETWEEN [column_value_1] AND [column_value_2];
如果结合上MySQL支持的函数和条件操作符,我们能够构建更加强大的搜索条件。
# 这里以Lower()做一个简单的实例
# Lower(): 将串转换成小写
# 将字符串进行小写转换,接着进行匹配检查
SELECT * FROM [table_name] WHERE Lower([column_name]) = [column_value];
逻辑操作符
多个过滤条件子句能够通过AND和OR这两个逻辑操作符进行组合,形成更强的过滤检查控制。
AND:检索满足所有给定条件的行;
OR:检索匹配任一给定条件的行;
# filter_condition: 搜索条件
# 检索出同时满足搜索条件filter_condition_1和filter_condition_2的行
SELECT * FROM [table_name] WHERE [filter_condition_1] AND [filter_condition_2];
# 检索出满足搜索条件filter_condition_1或filter_condition_2其中之一的行
SELECT * FROM [table_name] WHERE [filter_condition_1] AND [filter_condition_2];
WHERE可包含的AND和OR数目是任意,但是需要注意的是,AND的计算次序优先级是高于OR的。因而,为了避免在使用多数目的逻辑操作符导致整个语句的阅读困难,使用圆括号明确地分组相应的操作符是一种很好的实践。
SELECT *
FROM [table_name]
WHERE ([filter_condition_1] OR [filter_condition_2]) AND [filter_condition_2];
NULL值的检查
在MySQL的值类型中,NULL是一个相对比较特殊的值。
NULL代表着:无值(no value),它与字段包含0、空字符串或仅仅包含空格不同。它代表着数据的在初始化插入的时候未给该列赋予没有任何的值。
对于NULL值的检查,我们没法通过条件操作符进行判断,而是使用IS NULL子句进行判断。
# NULL值检查
SELECT * FROM [table_name] WHERE [column_name] IS NULL;
IN操作符
IN操作符用来指定一个匹配值清单,检索匹配清单内任一值的行。清单括在圆括号中,值之间用逗号分隔。
# 检索出column_name的列值匹配column_value_1或column_value_2其中之一的行
SELECT * FROM [table_name] WHERE [column_name] IN ([column_value_1], [column_value_2]);
# 上面的语句的效果等同于下面这条语句
SELECT *
FROM [table_name]
WHERE [column_name] = [column_value_1] OR [column_name] = [column_value_1];
在等值匹配列表的用法,IN操作符在功能上是和逻辑操作符OR等同的。但是,两者相比,IN操作符具有如下优点:
-
在使用长的合法选项清单时,
IN操作符的语法更清楚且更直观。 -
在使用
IN时,计算的次序更容易管理(因为使用的操作符更少)。 -
IN操作符一般比OR操作符清单执行更快。 -
IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句。
NOT操作符
NOT操作符的功能只有一个,就是否定它之后跟的任何条件。
# 检索出column_name的值不在清单内的行
SELECT * FROM [table_name] WHERE [column_name] NOT IN ([column_value_1], [column_value_2]);
# 检索出column_name的值在指定范围内容的行
SELECT * FROM [tableN_name] WHERE [column_name] NOT BETWEEN [column_value_1] AND [column_value_2];
MySQL支持使用
NOT对IN、BETWEEN和EXIST子句取反,这与多数其他DBMS允许使用NOT对各种条件取反有很大的差别。
通配符
前面的操作符相对来说,会比较适合值已知的检查过滤,值未知的情况会比较能力有限。
对于未知的值的过滤,通过通配符来构造出通配符搜索模式来进行过滤的这种做法,是一种相对比较合适的。
比较常有的通配符有两种:百分号(%)通配符和下划线(_)通配符:
| 通配符 | 功能 |
|---|---|
% | 匹配任何字符任意次数 |
_ | 匹配单个字符 |
虽然似乎
%通配符可以匹配任何东西,但有一个例外,即NULL。
在搜索子句中使用通配符,必须搭配LIKE操作符。
# 检索出column_name的字符串值的开头为"prefix"的行
SELECT * FROM [table_name] WHERE [column_name] LIKE 'prefix%';
# 检索出column_name的字符串值的第二到第七字符子串为"suffix"的行
SELECT * FROM [table_name] WHERE [column_name] LIKE '_suffix';
通配符在使用上的一些技巧:
-
不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
-
在确实需要使用通配符时,除非绝对有必要,否则不要把他们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。
-
仔细注意通配符的位置。如果放错了地方,可能不会返回想要的数据。
正则表达式
对于那些特殊的字符集合,例如:电话号码、电子邮件等。正则表达式,就能够提供更强大的功能来帮助你完成这部分文本的搜索过滤。
# regexp_pattern: 正则表达式字符串
SELECT * FROM [table_name] WHERE [column_name] REGEXP '[regexp_pattern]';
MySQL的正则表达式语法总体上和标准的正则表达式相同,但其仅支持标准正则表达式实现的一个很小的子集。虽然如此,在一些场景上,正则表达式咋一些过滤场景中,还是很方便的。
MySQL正则表达式的一些特点:
-
MySQL的正则表达式对特殊字符的匹配使用
\\,例如\\.匹配.; -
MySQL的正则表达式的字符集写法不同;
| 字符类 | 说明 |
|---|---|
[: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]) |
资料参考
-
《MySQL必知必会》