文章目录

  • 接上篇
  • 6. WHERE
  • 6.1 单条件过滤数据
  • 6.1 多条件过滤数据
  • 6.2 用通配符过滤
  • 6.3 用正则表达式过滤
  • 6.3.1 正则表达式
  • 6.3.1.1 or匹配符:|
  • 6.3.1.2 集合选一:[]
  • 6.3.1.3 元字符
  • 6.3.1.4 转义字符
  • 6.3.1.5 定位符
  • 6.3.1.6 字符集


接上篇

上篇主要介绍了一下简单的检索数据,接下来要介绍使用指定条件检索数据。
条件检索数据主要分两种:1. 使用普通条件,比如大于某值,等于指定值等等,2.在文本搜索中采用通配符或者正则表达式。

6. WHERE

6.1 单条件过滤数据

SQL中条件检索也就是过滤数据,都要使用WHERE子句。例如有如下表

+-----------+-------------+--------+--------+
| friend_id | names       | statue | weight |
+-----------+-------------+--------+--------+
|      1001 | Wangxiaodai |    178 |     71 |
|      1002 | Songxiaobao |    168 |     62 |
|      1003 | Lixiaomei   |    168 |     52 |
|      1004 | Guoxiaoyi   |   NULL |   NULL |
|      1005 | Xixiaopin   |    172 |     75 |
|      1006 | Penxiaoyuan |    171 |     60 |
+-----------+-------------+--------+--------+

选择语句如下

SELECT names, statue
FROM myfriends
WHERE statue < 175
ORDER BY statue DESC, names
LIMIT 2,3;

上面输出的是身高小于175,以身高降序姓名升序排名,从第3行(行号2)开始选择3行的friends。

mysql> SELECT names, statue
    -> FROM myfriends
    -> WHERE statue<175
    -> ORDER BY statue DESC,names
    -> LIMIT 2,3;
+-------------+--------+
| names       | statue |
+-------------+--------+
| Lixiaomei   |    168 |
| Songxiaobao |    168 |
+-------------+--------+
2 rows in set (0.00 sec)
# 由于筛选条件之后可选总行数是4行,所以从第3行开始选,只能选择2行
  • 注:上面的WHERE, ORDER BY, LIMIT 都是可选子句,但是如果都选择了,排序应该遵照这个顺序,不然会导致错误。

WHERE子句中的操作符如下表

操作符

意义

=

等于

<>或!=

不等于

<

小于

>

大于

<=

小于等于

>=

大于等于

BETWEEN

两值之间

除此之外,还有NULL检查,如下,看是否由身高缺失的。

SELECT names
FROM myfriends
WHERE statue IS NULL;
mysql> SELECT names
    -> FROM myfriends
    -> WHERE statue is NULL;
+-----------+
| names     |
+-----------+
| Guoxiaoyi |
+-----------+
1 row in set (0.00 sec)
6.1 多条件过滤数据

可以通过逻辑操作符组合多个判断条件,达到多条件过滤数据。
逻辑操作符有AND(与)和OR(或),IN(集合检查),NOT(否定)。
典型例子如下

...
WHERE statue<170 AND weight<60;
#输出175cm以下,60kg以下的
...
WHERE statue IN (170,178);
#输出170或者178的结果
  • 注:在使用多个逻辑操作符时需要考虑计算先后,在SQL中逻辑操作符AND和OR等级一样高,圆括号等级最高。
  • 注:如果要进行范围检索用BETWEEN子句。
mysql> SELECT names,statue,weight
    -> FROM myfriends
    -> WHERE statue BETWEEN 170 AND 180;
+-------------+--------+--------+
| names       | statue | weight |
+-------------+--------+--------+
| Wangxiaodai |    178 |     71 |
| Xixiaopin   |    172 |     75 |
| Penxiaoyuan |    171 |     60 |
+-------------+--------+--------+
3 rows in set (0.00 sec)
6.2 用通配符过滤

通配符 % 主要功能是匹配任何字符任意多次(包括0次)
通配符_ 主要功能是匹配任何字符一次
典型例子如下

SELECT names, statue, weight
FROM myfriends
WHERE names LIKE 'Zhang%'
#查找姓张的人
mysql> SELECT names,statue,weight
    -> FROM myfriends
    -> WHERE names LIKE 'Zhang%';
+-------------+--------+--------+
| names       | statue | weight |
+-------------+--------+--------+
| Zhangxiaoyi |   NULL |   NULL |
+-------------+--------+--------+
1 row in set (0.00 sec)

关键词LIKE是必不可少的。

6.3 用正则表达式过滤

在正则表达式中关键词变成REGEXP,那么过滤条件变成如下格式

...
WHERE names REGEXP '^Li'
mysql> SELECT names,statue,weight
    -> FROM myfriends
    -> WHERE names REGEXP '^LI';
+-----------+--------+--------+
| names     | statue | weight |
+-----------+--------+--------+
| Lixiaomei |    168 |     52 |
+-----------+--------+--------+
1 row in set (0.00 sec)

其中^是定位符,下面会介绍。

  • 注:正则表达式中REGEXP与LIKE最大的不同在于REGEXP匹配的是匹配子序列,而LIKE是匹配全序列,比如在上例中,如果语句如下,是找不到任何结果的,但是如果换成REGEXP能够找到两个结果。
...
WHERE names LIKE 'Li'
mysql> SELECT names,statue,weight
    -> FROM myfriends
    -> WHERE names LIKE 'LI';
Empty set (0.00 sec)

mysql> SELECT names,statue,weight
    -> FROM myfriends
    -> WHERE names REGEXP 'LI';
+-----------+--------+--------+
| names     | statue | weight |
+-----------+--------+--------+
| Lixiaomei |    168 |     52 |
| Zhangli   |   NULL |   NULL |
+-----------+--------+--------+
2 rows in set (0.00 sec)
6.3.1 正则表达式
6.3.1.1 or匹配符:|
...
WHERE names REGEXP 'ZHANG|ZHAN'
#匹配名字中有ZHANG或者ZHAN的人
6.3.1.2 集合选一:[]
...
WHERE emails REGEXP '[0123456789]'
#匹配邮箱地址中至少有一个数字的
#[0123456789]==[0|1|2|3|4|5|6|7|8|9]
6.3.1.3 元字符

正则表达式内部也可以实现通配符的功能,而且功能更多,只不过是通过叫元字符的组合而成的。元字符见下表。

元字符

意义

*

匹配0个以上的任意字符

+

匹配1个以上的任意字符


匹配0或1个任意字符

{n}

匹配n次

{n,}

匹配n次以上

{n,m}

匹配n次到m次

利用元字符,找到姓ZHANG或者ZHAN的人如下

...
WHERE names REGEXP '^ZHANG?'
#这样G和?组成能够匹配到有一个G和没有G的结果
...
WHERE email REGEXP '0{4}'
#这样就能匹配到邮箱地址中存在0000的值

在例如

mysql> SELECT names
    -> FROM myfriends
    -> WHERE names REGEXP 'zhangx*li';
+---------+
| names   |
+---------+
| Zhangli |
+---------+
1 row in set (0.00 sec)
#能够匹配0个x

mysql> SELECT names
    -> FROM myfriends
    -> WHERE names REGEXP 'zhangx+li';
Empty set (0.00 sec)
#+匹配不到0个x
6.3.1.4 转义字符

在MySQL的正则表达式中,转义字符为\\,对于一些特殊字符需要用转义字符,比如匹配’.’ 要用 ‘\\.’
转义字符还可以表示空白元字符

6.3.1.5 定位符

上面的例子中’^ZHANG’的 ^符号就是定位符,定位符主要设定匹配的位置,所有定位符见下表

定位符

意义

^

文本开头

$

文本结束

[[:<:]]

词的开头

[[:>:]]

词的结束

6.3.1.6 字符集

匹配常用的字符可以采用预定义的字符集,这样更方便,常用的字符集定义如下

字符集

意义

[:alpha:]

[a-zA-Z]

[:alnum:]

[a-zA-Z0-9]

[:digit:]

[0-9]