【问题标题】:mysql check if numbers are in a comma separated listmysql 检查数字是否在逗号分隔的列表中
【发布时间】:2010-04-20 09:43:09
【问题描述】:

我有一张这样的桌子:

UID(int) NUMBERS(blob)
----------------------
1        1,13,15,20
2        3,10,15,20
3        3,15

我想测试 3 和 15 是否在名为 NUMBERS 的 blob 中。并且可以看到LIKE %% 不能用

只选择 ID 为 2 和三个 scoulb 的行...

【问题讨论】:

标签: mysql list


【解决方案1】:

这个也可以:

SELECT * FROM table WHERE 3 IN (NUMBERS) AND 15 IN (NUMBERS)

使用 IN 将查看逗号分隔的字符串,例如。这两个

WHERE banana IN ('apple', 'banana', 'coconut')
WHERE 3 IN (2,3,6,8,90)

Info found on this page:

【讨论】:

  • 对接受自己的答案感到难过,因为对方也是对的。但 IN 似乎比 find_in_set 更正确,即使这也可以。
  • 喝了几杯啤酒后编码让我想到了这个问题。非常有帮助,谢谢!
  • 警告:这个答案可能是错误,因为foo IN ('1,2,3') ≡ foo IN (CAST('1,2,3' AS INT)) ≡ foo IN (1)。我想,find_in_set 是更明智的选择。
  • 正如 drdaeman 所指出的,当搜索的值是 INT 时,这不起作用,除非搜索的值恰好是集合中的第一个。
  • 我有一个视图,其中一列包含逗号分隔值,该列是使用 GROUP_CONCAT 创建的,这个解决方案似乎在那种情况下不起作用,但 find_in_set 可以,我想我可以分享我的调查结果。
【解决方案2】:

不是最漂亮的解决方案,但它有效:

select
   UID
from
   YOUR_TABLE
where
   find_in_set('3', cast(NUMBERS as char)) > 0
   and
   find_in_set('15', cast(NUMBERS as char)) > 0

请注意,这是字符串比较,因此您可能还需要将输入参数转换为 char。

【讨论】:

  • 感谢您的帮助。我找到了一个带有用于搜索逗号分隔值的示例的页面。我将其发布为答案。猜猜你的解决方案也可以正常工作
  • 这对我有用,而 IN 没有。示例如下: select id from users where find_in_set(uid,(select editors from items where article_id = 123))
  • 注意,find_in_set 在没有索引的情况下工作,所以可能会很慢
【解决方案3】:

您可以尝试如下:

 SELECT * FROM table_name WHERE FIND_IN_SET('3', NUMBERS) AND  FIND_IN_SET('15', NUMBERS)

【讨论】:

    【解决方案4】:

    还要检查这是否对任何人都有帮助

    为了消除 MySQL 中原生 FIND_IN_SET() 的限制的扩展功能,这个新的扩展版本 FIND_IN_SET_X() 提供了将一个列表与另一个列表进行比较的功能。

    mysql> SELECT FIND_IN_SET_X('x,c','a,b,c,d'); -> 3 
    

    Checkout this link for more details.

    【讨论】:

    • 有人知道我在哪里可以找到这个函数的详细信息吗?我找不到对它的任何引用,并且该链接不再有效...
    • 该函数“FIND_IN_SET_X”不存在。没有任何关于它的参考资料。
    • FIND_IN_SET_X() 似乎是用户定义的函数。 @Rodolfo Souza 的 answer 就是一个例子。
    【解决方案5】:

    为你完成的功能

    DELIMITER $$
    
    CREATE FUNCTION `FIND_IN_SET_X`(inputList TEXT,targetList TEXT) RETURNS INT(11)
        DETERMINISTIC
    BEGIN
      DECLARE limitCount INT DEFAULT 0 ;
      DECLARE counter INT DEFAULT 0 ;
      DECLARE res INT DEFAULT 0 ;
      DECLARE temp TEXT ;
      SET limitCount = 1 + LENGTH(inputList) - LENGTH(REPLACE(inputList, ',', '')) ;
      simple_loop :
      LOOP
        SET counter = counter + 1 ;
        SET temp = SUBSTRING_INDEX(SUBSTRING_INDEX(inputList, ',', counter),',',- 1) ;
        SET res = FIND_IN_SET(temp, targetList) ;
        IF res > 0 
        THEN LEAVE simple_loop ;
        END IF ;
        IF counter = limitCount 
        THEN LEAVE simple_loop ;
        END IF ;
      END LOOP simple_loop ;
      RETURN res ;
    END$$
    
    DELIMITER ;
    

    【讨论】:

      【解决方案6】:

      find_in_set_x

      在mysql中创建一个新函数并粘贴在下面(顺便说一下不是我的工作)

      BEGIN
      DECLARE limitCount INT DEFAULT 0;
      DECLARE counter INT DEFAULT 0;
      DECLARE res INT DEFAULT 0;
      DECLARE temp TEXT;
      SET limitCount = 1 + LENGTH(inputList) - LENGTH(REPLACE(inputList, ',',''));
      simple_loop:LOOP
      SET counter = counter + 1;
      SET temp = SUBSTRING_INDEX(SUBSTRING_INDEX(inputList,',',counter),',',-1);
      SET res = FIND_IN_SET(temp,targetList);
      IF res > 0 THEN LEAVE simple_loop; END IF;
      IF counter = limitCount THEN LEAVE simple_loop; END IF;
      END LOOP simple_loop;
      RETURN res;
      END
      

      【讨论】:

        【解决方案7】:

        试试这个查询:

        SELECT UID FROM table WHERE NUMBERS REGEXP "[[:<:]](3|10)[[:>:]]"
        

        [[:&lt;:]],[[:&gt;:]]:这些标记代表单词边界,因此它们分别匹配单词的开头和结尾。

        【讨论】:

          【解决方案8】:

          尝试以下方法:

          SELECT UID
          FROM TABLE
          WHERE
          concat(",",NUMBERS,",") like "%,1,%" 
          OR
          concat(",",NUMBERS,",") like "%,15,%";
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-06-10
            • 2020-12-28
            • 1970-01-01
            相关资源
            最近更新 更多