例子相似钉钉打卡考勤:SELECT * FROM fa_checkingroup
WHERE ( (concat(',',cdepartment_id,',') regexp concat(',(',replace('2,12',',','|'),'),') OR (concat(',',cuser_id,',') regexp concat(',(',replace('40',',','|'),'),'))) AND !(concat(',',wuser_id,',') regexp concat(',(',replace('40',',','|'),'),')) ) AND company_id
= 2mysql
问题描述 正则表达式
好比table1中有两条记录 name no a 2,9 b 8,10 sql
而后有一串字符串,是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的 ------------------------------ ui
Sql代码 设计
select * from table1 where concat(',',no,',') regexp concat(',0,|,1,|,2,|,3,|,4,'); code
或者: regexp
Sql代码
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条记录被选中。
固然也能够利用这种正则式 ',阅读,|,交友,|,围棋,|,足球,|,滑雪,', 但效率显然不如 ',(阅读|交友|围棋|足球|滑雪),' 这种了。