数据表 一个字段里储存了多个id匹配符合条件id怎么查询?

表task数据图片说明
实现功能:
数组:$data =Array ( [0] => 68 [1] => 69 );
receiver字段:储存了多个id以“,”分割

要把task表字段receiver储存的id要是有一个id符合$data数组的某个数据,就把task表对应数据查询出来?怎么实现?

select * from task where receiver like '%,'+id+',%' or receiver like id+',%' or receiver like '%,'+id or receiver = id

如果是mysql find_in_set() 方法了解下

先根据主键ID查出receiver字段 , 然后对receiver字段进行String.split(",") , 得到字符串数组或者集合 , 然后对数组和集合进行遍历 , 得到receiver下的各个ID
. 然后用参数和各个ID比对 , 如果能匹配上 , 就把该记录查出来 . 不知道我说的够不够明白

取出非空的receiver用split分解字段的到数组再比较不就得了

1、查询所有非空的receiver,放到一个字符串数组中,每个字符串是逗号分隔的id
2、逐个遍历$data 的每项看是否在查询出的receiver字符串数组中,如果找到了就退出循环,这样就可以找出想要的数据

select * from tablename
where FIND_IN_SET(1, receiver)
FIND_IN_SET这个方法可以,如果是mysql的话。
再加上mybatis 你用foreach和这个函数就可以做到了
遍历数组,生成FIND_IN_SET(1, receiver) or FIND_IN_SET(2, receiver) 就行了

 DROP FUNCTION IF EXISTS `find_in_myset`;

CREATE DEFINER = `root`@`%` FUNCTION `find_in_myset`(src varchar(100),dest varchar(100))
 RETURNS tinyint(1)
BEGIN
    set @i = length(src) - length(replace(src, ',', ''));
  set @left_str = src;
  while @i>0
  do 
  set @sub_str = substr(@left_str, 1, instr(@left_str, ',') - 1);
  set @left_str = substr(@left_str, length(@sub_str) + length(',') + 1);
  if FIND_IN_SET(trim(@sub_str), dest) then return 1;
    end if;
    end while;
    RETURN 0; 
END;

拿去试试看

 DROP FUNCTION IF EXISTS `find_in_myset`;

CREATE DEFINER = `root`@`%` FUNCTION `find_in_myset`(src varchar(100),dest varchar(100))
 RETURNS tinyint(1)
BEGIN
    set @i = length(src) - length(replace(src, ',', ''));
  set @left_str = src;
  while @i>0 do
        set @i = @i - 1;
        set @sub_str = substr(@left_str, 1, instr(@left_str, ',') - 1);
        set @left_str = substr(@left_str, length(@sub_str) + 2);
        if FIND_IN_SET(trim(@sub_str), dest) then return 1;
        end if;
    end while;
    if FIND_IN_SET(trim(@left_str), dest) then return 1;
    else return 0;
    end if; 
END;

 select 1 from dual where find_in_myset('7', '1,2,3,4,5,6')

其实可以用select * from A where ID IN('67,68,69') .给、如果id为67会出这条信息,68也会。69同理

这是一个通用函数,用来截取分割出来的自串
CREATE OR REPLACE TYPE ty_str_split IS TABLE OF VARCHAR2 (4000);

CREATE OR REPLACE FUNCTION fn_split (p_str IN VARCHAR2, p_delimiter IN VARCHAR2)

RETURN ty_str_split PIPELINED

IS

j INT := 0;

i INT := 1;

len INT := 0;

len1 INT := 0;

str VARCHAR2 (4000);

BEGIN

len := LENGTH (p_str);

len1 := LENGTH (p_delimiter);

WHILE j < len

LOOP

j := INSTR (p_str, p_delimiter, i);

IF j = 0

THEN

j := len;

str := SUBSTR (p_str, i);

PIPE ROW (str);

IF i >= len

THEN

EXIT;

END IF;

ELSE

str := SUBSTR (p_str, i, j - i);

i := j + len1;

PIPE ROW (str);

END IF;

END LOOP;

RETURN;

END fn_split;

/

测试:SELECT * FROM TABLE (fn_split ('1;;12;;123;;1234;;12345', ';;'));

结果:

1

12

123

1234

12345

然后...应该知道了吧

 SELECT
    f.*, u.user_gender,
    u.user_name,
    u.mobile_phone
FROM
    tb_sxd_police_indoor_task f
LEFT JOIN tb_sxd_user u ON u.user_id = f.sponsor
WHERE
exists (
    SELECT
        1
    FROM
        tb_police p
    WHERE
        p.provinceid = 440000
        FIND_IN_SET(p.pid, f.receiver)
)

你之前用的连接方式导致数据量增大,其实t表完全不必引用到from后面,改成这样速度应该能快一点。
我个人猜测你是用不到pid的,如果你一定要用pid的话,可以再写一个子查询

 SELECT
    f.*, u.user_gender,
    u.user_name,
    u.mobile_phone,
    (SELECT
        id
    FROM
        tb_police p
    WHERE
        p.provinceid = 440000) pid
FROM
    tb_sxd_police_indoor_task f
LEFT JOIN tb_sxd_user u ON u.user_id = f.sponsor
WHERE
exists (
    SELECT
        1
    FROM
        tb_police p
    WHERE
        p.provinceid = 440000
        FIND_IN_SET(p.pid, f.receiver)
)

我是觉得这个pid都一模一样的,应该没有查询出来的必要吧