程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> 其他數據庫知識 >> 更多數據庫知識 >> mysql字符串比較函數:concat和regexp

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條記錄被選中。

當然也可以利用這種正則式 ',閱讀,|,交友,|,圍棋,|,足球,|,滑雪,', 但效率顯然不如 ',(閱讀|交友|圍棋|足球|滑雪),' 這種了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved