MySQL find_in_set 与多个搜索字符串

Posted

技术标签:

【中文标题】MySQL find_in_set 与多个搜索字符串【英文标题】:MySQL find_in_set with multiple search string 【发布时间】:2011-06-28 06:36:03 【问题描述】:

我发现 find_in_set 只搜索单个字符串:-

find_in_set('a', 'a,b,c,d')

在上面的例子中,'a' 是唯一用于搜索的字符串。

有没有办法使用 find_in_set 类型的功能并通过多个字符串进行搜索,例如:-

find_in_set('a,b,c', 'a,b,c,d')

在上面的例子中,我想通过三个字符串 'a,b,c' 进行搜索。

我看到的一种方法是使用 OR

find_in_set('a', 'a,b,c,d') OR find_in_set('b', 'a,b,c,d') OR find_in_set('b', 'a,b,c,d')

除此之外还有什么办法吗?

【问题讨论】:

【参考方案1】:

没有本机功能可以做到这一点,但您可以使用以下技巧实现您的目标

WHERE CONCAT(",", `setcolumn`, ",") REGEXP ",(val1|val2|val3),"

【讨论】:

对于 Rails,它可以作为 Model.where('CONCAT(",", setcolumn, ",") REGEXP ?', [val1,val2,val3].join('|' )) 如果我的 val1|val2|val3 没有按照数据库条目的顺序排列怎么办。 惊人的答案! - 在替换 find_in_set 的查询中为我节省了几秒钟 您可以对 2 个表 T1 和 T2 执行此操作: .... where CONCAT(",", T1.setcolumn, ",") REGEXP CONCAT(",(", REPLACE (T2.setcolumn, ',', '|'), "),") 嗨,这是在 mysql 中工作的。但在 php 中,我添加了相同的内容。它的“语法错误,意外','在行中”的抛出错误 @AbijithAjayan 我已经通过在连接字符串中添加 Allow User Variables=true 解决了同样的问题【参考方案2】:

MySQL 函数find_in_set() 只能在一组字符串中搜索一个字符串。

第一个参数是一个字符串,因此无法让它将逗号分隔的字符串解析为字符串(根本不能在 SET 元素中使用逗号!)。第二个参数是一个 SET,它又由一个逗号分隔的字符串表示,因此您希望 find_in_set('a,b,c', 'a,b,c,d') 可以正常工作,但它肯定无法在任何 SET 定义中找到字符串 'a,b,c' - 它包含逗号。

【讨论】:

是的,你是对的。我认为解决我的问题的唯一方法是使用 OR 和 finset。像 "find_in_set('a', 'a,b,c,d') 或 find_in_set('b', 'a,b,c,d') 或 find_in_set('b', 'a,b,c,d ')"。【参考方案3】:

你也可以使用这个自定义函数

CREATE FUNCTION SPLIT_STR(
  x VARCHAR(255),
  delim VARCHAR(12),
  pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
       LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
       delim, ''); 

DELIMITER $$
    CREATE FUNCTION `FIND_SET_EQUALS`(`s1` VARCHAR(200), `s2`  VARCHAR(200)) 
    RETURNS TINYINT(1)
    LANGUAGE SQL
    BEGIN
          DECLARE a INT Default 0 ;
            DECLARE isEquals TINYINT(1) Default 0 ;
          DECLARE str VARCHAR(255);
          IF s1 IS NOT NULL AND s2 IS NOT NULL THEN
             simple_loop: LOOP
                 SET a=a+1;
                 SET str= SPLIT_STR(s2,",",a);
                 IF str='' THEN
                    LEAVE simple_loop;
                 END IF;
                 #Do  check is in set
                 IF FIND_IN_SET(str, s1)=0 THEN
                    SET isEquals=0;
                     LEAVE simple_loop;
                 END IF;
                 SET isEquals=1;
            END LOOP simple_loop;
          END IF;
        RETURN isEquals;
    END;
    $$
    DELIMITER ;

SELECT FIND_SET_EQUALS('a,c,b', 'a,b,c')- 1
SELECT FIND_SET_EQUALS('a,c', 'a,b,c')- 0
SELECT FIND_SET_EQUALS(null, 'a,b,c')- 0

【讨论】:

【参考方案4】:

@Pavel Perminov 的惊人回答! - 还有@doru 的精彩评论,用于动态检查..

从那里我为 PHP 代码 CONCAT(',','" . $country_lang_id . "', ',') REGEXP CONCAT(',(', REPLACE(YourColumnName, ',', '|'), '),') 制作的内容可能对正在寻找 PHP 的现成代码的人有用。

$country_lang_id = "1,2";

$sql = "select a.* from tablename a where CONCAT(',','" . $country_lang_id . "', ',') REGEXP CONCAT(',(', REPLACE(a.country_lang_id, ',', '|'), '),') ";

【讨论】:

【参考方案5】:

你也可以使用like命令例如:

where setcolumn like '%a,b%'

where 'a,b,c,d' like '%b,c%'

在某些情况下可能会起作用。

【讨论】:

如何使用 [where 'a,b,c,d' like '%b,c%'] 它也可能是 'c,b'。所以我认为这不是好的解决方案!【参考方案6】:

您可以使用 in 从两个值中查找匹配值

SELECT * FROM table WHERE  myvals in (a,b,c,d)

【讨论】:

IN 子句不带变量。它使用列w3resource.com/sql/in-operator/sql-in-operator.php

以上是关于MySQL find_in_set 与多个搜索字符串的主要内容,如果未能解决你的问题,请参考以下文章

MySQL查询某个字段包含某个值--FIND_IN_SET

项目常用的几个mysql函数

具有多个值的 FIND_IN_SET

mysql 中LIKE 与FIND_IN_SET 与关联表left join 速度效率比较

mysql中的find_in_set()函数

mysql中的find_in_set()函数