Je trouve que find_in_set recherche uniquement par une seule chaîne: -
find_in_set('a', 'a,b,c,d')
Dans l'exemple ci-dessus, "a" est la seule chaîne utilisée pour la recherche.
Existe-t-il un moyen d'utiliser le type de fonctionnalité find_in_set et d'effectuer une recherche par plusieurs chaînes, comme par exemple: -
find_in_set('a,b,c', 'a,b,c,d')
Dans l'exemple ci-dessus, je souhaite effectuer une recherche selon trois chaînes 'a, b, c'.
Je vois l’utilisation deOU
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')
Y a-t-il un autre moyen que celui-ci?
il n'y a pas de fonction native pour le faire, mais vous pouvez atteindre votre objectif en utilisant l'astuce suivante
WHERE CONCAT(",", `setcolumn`, ",") REGEXP ",(val1|val2|val3),"
La fonction MySQL find_in_set()
ne peut rechercher qu’une chaîne dans un ensemble de chaînes.
Le premier argument est une chaîne, il n'y a donc aucun moyen de lui faire analyser votre chaîne séparée par des virgules en chaînes (vous ne pouvez pas utiliser les virgules dans les éléments SET!). Le deuxième argument est un SET, qui à son tour est représenté par une chaîne séparée par des virgules, d'où votre souhait de find_in_set('a,b,c', 'a,b,c,d')
qui fonctionne bien, mais il ne peut sûrement pas trouver une chaîne 'a,b,c'
dans aucun SET par définition - il contient des virgules.
Vous pouvez également utiliser cette fonction personnalisée
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
Vous pouvez également utiliser la commande like par exemple:
where setcolumn like '%a,b%'
ou
where 'a,b,c,d' like '%b,c%'
qui pourrait fonctionner dans certaines situations.