it-swarm.com.de

MySQL find_in_set mit mehreren Suchstrings

Ich finde, dass find_in_set nur mit einer einzelnen Zeichenfolge sucht: - 

find_in_set('a', 'a,b,c,d')

Im obigen Beispiel ist 'a' die einzige für die Suche verwendete Zeichenfolge.

Gibt es eine Möglichkeit, die Funktionalität von find_in_set zu verwenden und nach mehreren Zeichenfolgen zu suchen, z. 

find_in_set('a,b,c', 'a,b,c,d')

Im obigen Beispiel möchte ich nach drei Zeichenketten 'a, b, c' suchen.

Eine Möglichkeit, die ich sehe, ist die Verwendung vonODER

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

Gibt es einen anderen Weg als diesen?

37

es gibt keine native Funktion, um dies zu tun, aber Sie können Ihr Ziel mit dem folgenden Trick erreichen

WHERE CONCAT(",", `setcolumn`, ",") REGEXP ",(val1|val2|val3),"
84
Pavel Perminov

Die MySQL-Funktion find_in_set() kann nur nach einem String in einem String-Satz suchen.

Das erste Argument ist eine Zeichenfolge. Es gibt also keine Möglichkeit, die durch Kommas getrennte Zeichenfolge in Zeichenfolgen zu analysieren (in SET-Elementen können Sie keine Kommas verwenden!). Das zweite Argument ist ein SET, das wiederum durch eine durch Kommas getrennte Zeichenfolge dargestellt wird. Daher ist Ihr Wunsch nach find_in_set('a,b,c', 'a,b,c,d') gut. Dies funktioniert zwar einwandfrei, es kann jedoch in keinem SET per Definition ein String 'a,b,c' gefunden werden.

14

Sie können diese benutzerdefinierte Funktion auch verwenden

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
1
user3740702

Sie können den like-Befehl beispielsweise auch verwenden:

where setcolumn like '%a,b%'

oder 

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

was in manchen Situationen funktionieren könnte.

0
Jon Gabrielson