MYSQL 多关键字相关文章查询方法
2010-05-01 13:53
246 查看
取得文章关键字为keywords
表news的关键字字段为keyword
keywords=keywords.replace(',','|');
String sql="SELECT * FROM news WHERE keyword REGEXP '"+keywords+"' ORDER BY id ";
由于某些原因,有时候我们没有按照范式的设计准则而把一些属性放到同一个字符串字段中。比如个人兴趣,有时候我们设计表为
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 5.1参考手册 - 12.3.1. 字符串比较函数 - REGEXP (RLIKE)
http://dev.mysql.com/doc/refman/5.1/zh/functions.html#string-comparison-functions
MySQL 5.1参考手册 - 附录G:MySQL正则表达式
http://dev.mysql.com/doc/refman/5.1/zh/regexp.html
表news的关键字字段为keyword
keywords=keywords.replace(',','|');
String sql="SELECT * FROM news WHERE keyword REGEXP '"+keywords+"' ORDER BY id ";
由于某些原因,有时候我们没有按照范式的设计准则而把一些属性放到同一个字符串字段中。比如个人兴趣,有时候我们设计表为
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 5.1参考手册 - 12.3.1. 字符串比较函数 - REGEXP (RLIKE)
http://dev.mysql.com/doc/refman/5.1/zh/functions.html#string-comparison-functions
MySQL 5.1参考手册 - 附录G:MySQL正则表达式
http://dev.mysql.com/doc/refman/5.1/zh/regexp.html
相关文章推荐
- MySQL单表多关键字模糊查询的实现方法
- MySQL时间日期查询相关函数与方法
- DEDECMS相关文章以关键字相关的修改方法(自定义函数)
- thinkphp mysql查询中文某关键字方法,单引号和双引号共用
- MySQL单表多关键字模糊查询的实现方法
- PHP使用mysql_fetch_row查询获得数据行列表的方法
- PHP使用mysql_fetch_object从查询结果中获取对象集的方法
- MySQL带IN关键字的查询
- Mysql锁查询相关指令
- PHP简单实现“相关文章推荐”功能的方法
- mysql处理海量数据时的一些优化查询速度方法
- mysql查询中文问题解决方法
- percona-toolkit之pt-kill 杀掉mysql查询或连接的方法
- mysql查询时,offset过大影响性能的原因与优化方法
- MySQL之——查询重复记录、删除重复记录方法大全
- 查询mysql中执行效率低的sql语句的方法
- MYSQL类型不支持原生SQL查询解决方法
- MySQL中的?加关键字查询命令用法
- 浅谈mysql中多表不关联查询的实现方法