MySQL find_in_set с несколькими поисковыми строками - PullRequest
39 голосов
/ 16 февраля 2011

Я считаю, что 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'.

Один способ, который я вижу, - это использование ИЛИ

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')

Есть ли другой способ, кроме этого?

Ответы [ 5 ]

97 голосов
/ 04 октября 2014

нет встроенной функции для этого, но вы можете достичь своей цели, используя следующий трюк

WHERE CONCAT(",", `setcolumn`, ",") REGEXP ",(val1|val2|val3),"
14 голосов
/ 21 февраля 2011

Функция MySQL find_in_set() может искать только одну строку в наборе строк.

Первый аргумент - это строка, поэтому нет способа заставить ее разобрать строку, разделенную запятыми, в строки (вы не можете использовать запятые в элементах SET вообще!). Второй аргумент - это SET, который, в свою очередь, представлен строкой, разделенной запятыми, отсюда и ваше желание find_in_set('a,b,c', 'a,b,c,d'), которое работает нормально, но он определенно не может найти строку 'a,b,c' в любом наборе SET по определению - он содержит запятые.

1 голос
/ 14 января 2016

Вы также можете использовать эту пользовательскую функцию

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
0 голосов
/ 20 февраля 2017

вы можете использовать, чтобы найти значения совпадений из двух значений

SELECT * FROM table WHERE  myvals in (a,b,c,d)
0 голосов
/ 16 октября 2013

Вы также можете использовать команду like, например:

where setcolumn like '%a,b%'

или

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

, который может работать в некоторых ситуациях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...