MySQL如何检查数字是否在逗号分隔的列表中

31

我有一个像这样的表格:

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

我想测试数字3和15是否在名为NUMBERS的Blob中。并且不能使用LIKE %%。

只有ID为2和3的行才能被选中...


可能是重复的问题:MySQL查询在逗号分隔的字符串中查找值 - Salman A
8个回答

48

这个也可以:

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)

这个页面上找到的信息:


1
几杯啤酒后编程让我遇到了这个问题。非常有帮助,谢谢! - psx
24
警告:这个答案可能是有误的,因为 foo IN ('1,2,3') ≡ foo IN (CAST('1,2,3' AS INT)) ≡ foo IN (1)。我猜测使用 find_in_set 更加合理。 - drdaeman
4
正如drdaeman所指出的,当要查找的值是整数时,除非要查找的值恰好是集合中的第一个值,否则此方法无效。 - JoshHetland
1
我有一个视图,其中一列包含逗号分隔的值,该列是使用GROUP_CONCAT创建的,但是在这种情况下,此解决方案似乎无法正常工作,但是find_in_set可以,我想分享一下我的发现。 - Q_ro
find_in_set 是更准确的答案。 - Norielle Cruz
显示剩余2条评论

40

虽然不是最优美的解决方案,但它起作用:

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类型。


谢谢你的帮助。我找到了一个搜索逗号分隔值的示例页面,并将其发布为答案。我猜你的解决方案也可以很好地工作。 - Tillebeck
1
这对我有效,而IN则不行。以下是示例:从用户中选择ID,其中uid在文章编辑为123的那些编辑中。 - Johnathan Elmore
请注意,find_in_set函数在没有索引的情况下可能会很慢。 - aswzen

22

您可以尝试以下方式:

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

8

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

例如:

Also check if this is helpful to anyone

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

请查看此链接以获取更多详细信息:

点击这里

。该链接与字符串函数相关。

1
有人知道我在哪里可以找到这个函数的详细信息吗?我找不到任何参考资料,链接也已经失效了... - Matthew
4
那个函数“FIND_IN_SET_X”不存在。任何地方都没有关于它的引用。 - Memochipan
1
FIND_IN_SET_X() 看起来是一个用户自定义的函数。@Rodolfo Souza 的答案是一个示例。 - Lacek

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 ;

0

请尝试以下方法:

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

0

尝试这个查询:

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

[[:<:]],[[:>:]]: 这些标记表示单词边界,因此它们分别匹配单词的开头和结尾。


0

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接