Tester si un champs contient une partie d'un autre

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Tester si un champs contient une partie d'un autre

par toony.m » 13 oct. 2006, 15:11

Merci pour tous ces éclaircissements, et c'est vrai que la seule solution que j'ai trouvé est proche de l'artillerie lourde. :cry:

Je verrais à long terme si le temps des requetes est trop long..

Merci.

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.

par Hubert Roksor » 13 oct. 2006, 14:22

Comme le dit pascal, si tu normalisais la table tu aurais beaucoup moins d'ennuis. Beaucoup, beaucoup moins.

Premièrement, une mauvaise nouvelle : il est pratiquement impossible de vérifier qu'un champs contient une portion arbitraire" d'un autre champs sans employer de l'artillerie lourde, très lourde. Et ce, parce qu'il existe un très grand nombre de possibilités, par exemple "c", "cd", "cdd", "cdd,", "d", "dd", "dd,", ",c", ",cd", etc... Au pire, tu peux essayer ce dont parle pascal et faire une requête par type (cdd, cdi, mission, etc...). En fait, tu pourrais même les aggréger en une requête unique avec UNION. (UNION DISTINCT pour éviter les doublons)

D'un autre côté, si le nombre de valeurs contenues dans le champs est fini et égal ou inférieur à 64 et que ton serveur de base de données est MySQL tu pourrais songer à utiliser le type de données SET.

[Edit: hmm, je ne suis pas sûr que l'on puisse mettre plusieurs valeurs de chaque côté de FIND_IN_SET()... je mettrai à jour mon post plus tard]

par pascaltje » 13 oct. 2006, 12:09

et ben voila, on met plusieurs informations dans un seul champ et on est embeté...

as tu essayé un truc du style:

Code : Tout sélectionner

SELECT ... ... WHERE champ1 LIKE '%cdd%' AND champ2 LIKE '%cdd%'
ça oblige à faire plusieurs requetes, mais bon, c'est mieux que rien.

A+

Pascal

Tester si un champs contient une partie d'un autre

par toony.m » 13 oct. 2006, 11:16

Salut!

Voici mon problème, c'est pour un push-mail:
J'ai 2 champs différents chacun dans une table.
un champs n°1 "contrat" dans la table "alertes" et
un champs n°2 "contrat" dans la table "annonces".

J'essaye de trouver une requete SQL qui puisse permettre de rechercher si le champs n°1 peut trouver si le champs n°2 contient une partie du champs n°1. :shock:
j'explique:
champs1="cdd,cdi,mission," et le champs2="cdd,mission,"
sachant que les champs peuvent varier à chaque fois et contenir le terme "cdd," et/ou "cdi," et/ou "mission,".

Comment faire ?
J'ai tenté avec REGEXP mais j'ai du mal à maitriser cette fonction...[/u]