例子相似釘釘打卡考勤: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條記錄被選中。
固然也能夠利用這種正則式 ',閱讀,|,交友,|,圍棋,|,足球,|,滑雪,', 但效率顯然不如 ',(閱讀|交友|圍棋|足球|滑雪),' 這種了。