mysql字符串比较函数:concat和regexp
问题描述
比如table1中有两条记录
name no
a 2,9
b 8,10
然后有一串字符串,是0,1,2,3,4
然后通过一条sql,找出no为2,9的记录来```
因为字符串中有2,数据中也有2
详细解释
------------------------------
表的字段就是
name no
a 2,9
b 8,10
字符串是str="0,1,2,3,4"
接下来就是查 no字段里跟str里有交集的记录
查询的结果就是name=a的,no=2,9的记录。
1
2
|
select * from table1 where concat( ',' ,no, ',' ) regexp concat( ',0,,1,,2,,3,,4,' ); |
或者:
1
2
|
select * from table1 where concat( ',' ,no, ',' ) regexp concat( ',(' ,replace( '0,1,2,3,4' , ',' , '' ), '),' ); |
由于某些原因,有时候我们没有按照范式的设计准则而把一些属性放到同一个字符串字段中。比如个人兴趣,有时候我们设计表为
create table members (uid int primary key,uname varchar(20),hobby varchar(100));
表中内容如下
mysql> select * from members;
+-----+-------+---------------------------------+
uid uname hobby
+-----+-------+---------------------------------+
1 AAAA 音乐,电影,网络,篮球,阅读,乒乓球
2 BBBB 音乐,阅读,乒乓球,发呆,围棋,参禅
3 CCCC 交友,乒乓球
4 DDDD 台球,网络,看书,旅游
5 EEEE 音乐,发呆,下围棋,参禅
+-----+-------+---------------------------------+
4 rows in set (0.00 sec)
如果我们现在想查找一个与某个用户X (阅读,交友,围棋,足球,滑雪)有着相同爱好的会员记录 如果来操作呢?
在其它数据库中,我们能只通过程序来或者存储过程来分解这个 "阅读,交友,围棋,足球,滑雪" 字符串为单独的爱好项目,然后一个一个进行 like '%xxxx%' 来查询。 但在MySQL中我们可以直接利用这个regexp正规表达式 来构造SQL语句来实现。
首先我们把 '阅读,交友,围棋,足球,滑雪' 转换成为正则式 为 '阅读交友围棋足球滑雪' , 在正则表达式中为 '或' 的意思
mysql> select replace('阅读,交友,围棋,足球,滑雪',',','');
+---------------------------------------------+
replace('阅读,交友,围棋,足球,滑雪',',','')
+---------------------------------------------+
阅读交友围棋足球滑雪
+---------------------------------------------+
1 row in set (0.00 sec)
这样我们可以用SQL语句如下。
mysql> select * from members where hobby regexp replace('阅读,交友,围棋,足球,滑雪',',','');
+-----+-------+---------------------------------+
uid uname hobby
+-----+-------+---------------------------------+
1 AAAA 音乐,电影,网络,篮球,阅读,乒乓球
2 BBBB 音乐,阅读,乒乓球,发呆,围棋,参禅
3 CCCC 交友,乒乓球
5 EEEE 音乐,发呆,下围棋,参禅
+-----+-------+---------------------------------+
3 rows in set (0.00 sec)
如上语句我们可以通过一句SQL得到所有hobby包含 '阅读,交友,围棋,足球,滑雪' 任一项的记录。
但上述的语句中还有一点小的缺陷,那就是把 '下围棋' 这一条也选择了出来,如果精确匹配的话这条记录不应该被选中。为了避免这种情况,我们对SQL语句做如下改进。
把正则式改为 ',(阅读交友围棋足球滑雪),' 也就是要求匹配项前后必须有一个界定符","
mysql> select concat(',(',replace('阅读,交友,围棋,足球,滑雪',',',''),'),');
+---------------------------------------------------------------+
concat(',(',replace('阅读,交友,围棋,足球,滑雪',',',''),'),')
+---------------------------------------------------------------+
,(阅读交友围棋足球滑雪),
+---------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select * from members
-> where concat(',',hobby,',') regexp
-> concat(',(',replace('阅读,交友,围棋,足球,滑雪',',',''),'),');
+-----+-------+---------------------------------+
uid uname hobby
+-----+-------+---------------------------------+
1 AAAA 音乐,电影,网络,篮球,阅读,乒乓球
2 BBBB 音乐,阅读,乒乓球,发呆,围棋,参禅
3 CCCC 交友,乒乓球
+-----+-------+---------------------------------+
3 rows in set (0.00 sec)
这样避免了第5条记录被选中。
关键字:mysql、函数、记录
新文章:
- CentOS7下图形配置网络的方法
- CentOS 7如何添加删除用户
- 如何解决centos7双系统后丢失windows启动项
- CentOS单网卡如何批量添加不同IP段
- CentOS下iconv命令的介绍
- Centos7 SSH密钥登陆及密码密钥双重验证详解
- CentOS 7.1添加删除用户的方法
- CentOS查找/扫描局域网打印机IP讲解
- CentOS7使用hostapd实现无AP模式的详解
- su命令不能切换root的解决方法
- 解决VMware下CentOS7网络重启出错
- 解决Centos7双系统后丢失windows启动项
- CentOS下如何避免文件覆盖
- CentOS7和CentOS6系统有什么不同呢
- Centos 6.6默认iptable规则详解