par
Hubert Roksor » 13 oct. 2006, 14:48
Après vérification, le premier argument de
FIND_IN_SET() doit être une chaîne, ce qui veut dire qu'on ne peut pas faire de FIND_IN_SET() entre deux champs de type SET parce que cela ne fonctionnera pas si le premier champs contient plusieurs valeurs.
Puisque le type SET est en fait un "
bit array" il est possible d'utiliser des opérateurs logiques dessus à condition que les
deux champs soient strictement identiques (mêmes valeurs même ordre lors de la déclaration du SET). En l'occurence, pour trouver des champs ayant au moins une correspondance on peut utiliser l'opérateur AND. Exemple, quelques annonces et alertes:
Code : Tout sélectionner
CREATE TABLE alertes (
alerte_id smallint(5) unsigned NOT NULL auto_increment,
contrat set('cdd','cdi','mission') NOT NULL,
PRIMARY KEY (alerte_id)
);
INSERT INTO alertes (contrat) VALUES ('cdi'), ('cdd,cdi'), ('cdi,mission'), ('mission');
CREATE TABLE annonces (
annonce_id smallint(5) unsigned NOT NULL auto_increment,
contrat set('cdd','cdi','mission') NOT NULL,
PRIMARY KEY (annonce_id)
);
INSERT INTO annonces (contrat) VALUES ('cdd'), ('cdi'), ('mission'), ('cdd,cdi'), ('cdd,cdi,mission'), ('cdi,mission'), ('mission'), ('cdd,mission'), ('cdi,mission'), ('cdi'), ('cdd,cdi'), ('cdd,cdi,mission'), ('cdd'), ('mission');
Récupérer toutes les alertes correspondant aux annonces existantes
Code : Tout sélectionner
SELECT *
FROM alertes al
JOIN annonces an ON an.contrat & al.contrat
Un gros bémol cependant, à l'heure actuelle, MySQL ne peut pas utiliser d'index pour ce genre de requêtes. Cela signifie que cette requête peut devenir
très très lente au fur et à mesure que le nombre d'enregistrements augmente. C'est aussi vrai (et encore plus) pour toute solution basée sur LIKE. Des tables normalisées ne souffriraient pas de ce problème.
Après vérification, le premier argument de [url=http://dev.mysql.com/doc/refman/5.0/fr/string-functions.html#id2767558]FIND_IN_SET[/url]() doit être une chaîne, ce qui veut dire qu'on ne peut pas faire de FIND_IN_SET() entre deux champs de type SET parce que cela ne fonctionnera pas si le premier champs contient plusieurs valeurs.
Puisque le type SET est en fait un "[url=http://en.wikipedia.org/wiki/Bit_array]bit array[/url]" il est possible d'utiliser des opérateurs logiques dessus à condition que les [b]deux champs soient strictement identiques[/b] (mêmes valeurs même ordre lors de la déclaration du SET). En l'occurence, pour trouver des champs ayant au moins une correspondance on peut utiliser l'opérateur AND. Exemple, quelques annonces et alertes:
[code]CREATE TABLE alertes (
alerte_id smallint(5) unsigned NOT NULL auto_increment,
contrat set('cdd','cdi','mission') NOT NULL,
PRIMARY KEY (alerte_id)
);
INSERT INTO alertes (contrat) VALUES ('cdi'), ('cdd,cdi'), ('cdi,mission'), ('mission');
CREATE TABLE annonces (
annonce_id smallint(5) unsigned NOT NULL auto_increment,
contrat set('cdd','cdi','mission') NOT NULL,
PRIMARY KEY (annonce_id)
);
INSERT INTO annonces (contrat) VALUES ('cdd'), ('cdi'), ('mission'), ('cdd,cdi'), ('cdd,cdi,mission'), ('cdi,mission'), ('mission'), ('cdd,mission'), ('cdi,mission'), ('cdi'), ('cdd,cdi'), ('cdd,cdi,mission'), ('cdd'), ('mission');[/code]
Récupérer toutes les alertes correspondant aux annonces existantes
[code]SELECT *
FROM alertes al
JOIN annonces an ON an.contrat & al.contrat[/code]
Un gros bémol cependant, à l'heure actuelle, MySQL ne peut pas utiliser d'index pour ce genre de requêtes. Cela signifie que cette requête peut devenir [b]très très lente[/b] au fur et à mesure que le nombre d'enregistrements augmente. C'est aussi vrai (et encore plus) pour toute solution basée sur LIKE. Des tables normalisées ne souffriraient pas de ce problème.