有时候,需要用到模糊查询,那么就会用到MySQL LIKE 子句。如下示例:
SELECT field1, field2,...fieldN
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
但是,MySQL中like子句并未提供类似于in子句的查询集合:
select * from table where field in (value1,value2,value3,…)
只能有这样:
select * from table where field like value1 ;
或者这样:
select * from table where field like value1 or field like value2 . . .
再或者这样:
select * from table where field REGEXP 'value1|value2. . .'
这么看来的话,使用MySQL正则,大致可以实现我们的需求,这个时候,需要我们对后面的结果集,做一个转化。
举例:有两张表,一张订阅表,一张菜单表。我需要通过订阅表,知道用户订阅了菜单表中的某一菜单及其菜单下的各个文件或者文件夹。一个用户可以有多个订阅表记录,一条订阅表的记录可能对应着多个菜单表的数据;这个时候,本文所说的就出现了。like的条件即某一查询的结果集,需要达到类似in子句的效果。
首先,根据订阅表的subscribeUserId(订阅人Id)搜索出其下所有的订阅目录:
SELECT
subscribePath
FROM
h_subscribe
WHERE
subscribeUserId = #{subscribeUserId}
结果集如下:
subscribePath |
/数据中心/共用文档/ |
/数据中心/共用音乐/ |
此时,需要距离我们所需要的MySQL正则表达式的条件相差甚远,但是,我们可以通过MySQL中的
GROUP_CONCAT 函数,将结果集,转化为一字符串:
SELECT
GROUP_CONCAT(
s.subscribePath SEPARATOR '|'
) AS path
FROM
(
SELECT
subscribePath
FROM
h_subscribe
WHERE
subscribeUserId = #{subscribeUserId}
) s
关于GROUP_CONCAT的参数,逗号分隔(默认),得到的字符串,仍需要用REPLACE函数进行处理,将逗号(,)替换为竖线(|);然鹅,其可以指定SEPARATOR ,所以,我们可以一步到位,得到结果集:
path |
F:/数据中心/共用文档/|F:/数据中心/共用音乐/ |
至此,和上文开始提到的正则REGEXP一致,就可以进行类似:
select * from table where field like ('value1', 'value2' . . .)
至此,贴出SQL:
SELECT
*
FROM
h_menu
WHERE
path REGEXP (
SELECT
GROUP_CONCAT(
s.subscribePath SEPARATOR '|'
) AS path
FROM
(
SELECT
subscribePath
FROM
h_subscribe
WHERE
subscribeUserId = #{subscribeUserId}
) s
)
总结,本次整理源自自己不想通过for循环遍历,然后模糊查询,仅仅做个人测试用途,其他方面如查询性能等未作探究,如您有建议,还请多多赐教,小白不胜感激涕零~.~。