【问题标题】:MySQL find_in_set with multiple search stringMySQL find_in_set 与多个搜索字符串
【发布时间】: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')

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

【问题讨论】:

    标签: mysql search


    【解决方案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)
        

        【讨论】:

        猜你喜欢
        • 2016-09-02
        • 2022-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-06
        相关资源
        最近更新 更多