Sql: where nom like dans un sql déjà existant

Fermé
westernz - 3 août 2011 à 12:17
 westernz - 5 août 2011 à 14:58
Bonjour,

En principe on écrit ceci : (si je ne me trompe pas)
$sql = "select figuratif from matable where nom like '%mot%';

Est il possible de passer cette requete dans ceci :
$sql = "select figuratif, subjectif, état, origine, époque from matable where etat = 'terminé' AND Origine = 'france' AND subjectif = nom like '%mot%';

Mon souci est d'intégré "nom like" dans une requête existante, sachant que nom like ne devra chercher les correspondances que dans 1 des champ.

J'aimerai pouvoir cherche mes mots clé uniquement dans le champs figuratif, mais mon select dans le quel je vais inclure cette variable a besoin de tester plusieurs champs pour d'autres fonctions. Je vais déjà avoir 2 requête dont une en while qui contiendra l'autre. Est il possible de déterminer le champs de recherche dans le where pour "nom like" ?

Bonne journée


A voir également:

9 réponses

blux Messages postés 26003 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 25 avril 2024 3 289
3 août 2011 à 14:16
Salut,

si tu mets "AND subjectif = nom", c'est que tu veux faire une jointure.

Il te faut donc deux tables, tu n'en n'as qu'une seule décrite.

Donc, je ne comprends pas ce que tu souhaites faire...
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 607
3 août 2011 à 16:10
D'où vient ce "nom" ? De quelle table ?

0
mpmp93 Messages postés 6652 Date d'inscription mercredi 13 avril 2011 Statut Membre Dernière intervention 28 septembre 2015 1 339
3 août 2011 à 16:14
Bonjour,

Vous avez une erreur de syntaxe:

AND subjectif = nom like '%mot%';

Like est un opérateur au même titre que =

Like pour ce genre de recherche:
- ... like 'xxx%' => remonte tout ce qui commence par xxx
- ... like '%xxx%' => remonte tout ce qui contient xxx
- like '%xxx' => remonte tout ce qui finit par xxx

= pour ce genre de recherche:
- ... = 'xxx' => remonte tout ce qui contient strictement xxx avec rien d'autre devant et/ou dedans et/ou derrière!

A+
0
Ok j'ai compris le principe et mon erreur de compréhension
Merci :)
Bonne journée
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bonjour,

Une dernier question sur ce sujet.
Dans le condition d'un where, est-il autorisé une condition pour deux champs ?

genre :

WHERE champ1, champ2 = truc;

Ou doit on impérativement duplique truc pour chacun des deux :
WHERE champ1 = truc AND champ2 = truc

C'est qu'a force d'en ajouter je risque rendre possible de passer la limites des 5000 caractères sql :( Si l'utilisateur cocher tous les filtre et met un max de mots clé... ca dépassera.

Je cherche dons à limiter un peu
0
blux Messages postés 26003 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 25 avril 2024 3 289
4 août 2011 à 15:37
Tu peux limiter le cas échéant avec un IN :

SELECT toto FROM table WHERE titi in ('a','b','c') and toto in ('paris','lyon');
0
mpmp93 Messages postés 6652 Date d'inscription mercredi 13 avril 2011 Statut Membre Dernière intervention 28 septembre 2015 1 339
4 août 2011 à 15:39
Bonjour,

Concernant: WHERE champ1, champ2 = truc;

Il faut un opérateur logique. Vous en avez deux: AND et OR

Leur précédence est équivalente à * et + en arithmétique. Exemple:

(3 + 2) * 5 est différent de 3 + (2 * 5)

Si je remplace * et + par AND et OR, j'aurai

WHERE (x = 3 OR y = 2) AND z=5
WHERE x=3 OR (y=2 AND z=5)

ces opérateurs AND et OR sont incontournables.

Donc, il faut:

WHERE champ1='xxx' AND champ2='xxx'

prenons le cas d'une bdd. Vous voulez sortir tous les hommes sans distinction d'âge et toutes les femmes entre 20 et 35 ans:

SELECT * CLIENTS
WHERE sexe='H' OR (sexe='F' AND age BETWEEN(20,35)

C'est clair?

A+
0
mpmp93 Messages postés 6652 Date d'inscription mercredi 13 avril 2011 Statut Membre Dernière intervention 28 septembre 2015 1 339
4 août 2011 à 15:41
Il faut limiter les filtres sur données. Avec de très grosses base de données, le filtrage est très fortement ralenti sur des champs non indexés
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 607
4 août 2011 à 15:34
Les différentes conditions doivent être délimitées avec le mot-clé AND.

0
Pour AND et OR je connais.
Je me demandais juste si quelque d'autre existé, comme "in"

A ce propos, in est il compatible avec par exemple

WHERE figuratif like "%mot1%" AND figuratif like "%mot2%" AND forum_desc like "%mot1%" AND forum_desc like "%mot2%";

Je suppose que c'est trop demandé ?!
Non ?

Car de nez je ne vois pas comment cumulé l'atout de in (que je retient car très util) avec like qui en principe remplace un "=" amoins que ceci soit juste :

WHERE %mot1% in ('figuratif', 'forum_desc') AND %mot2% in ('figuratif', 'forum_desc');

Ou pire... vous allez me prendre pour un fou !

WHERE ("%mot1%" OR "%mot2%") in ('figuratif', 'forum_desc');

Je cherche... je vais essayez seul mais ... je vais aussi aller voir les info sur IN avant ;)

Bonne journée
Et Merci pour ces aides :)
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 607
4 août 2011 à 20:36
je vais aussi aller voir les info sur IN avant ;)

Bonne idée, parce que sans vouloir te vexer... tu n'y es pas du tout pour le IN ;-)
0
mpmp93 Messages postés 6652 Date d'inscription mercredi 13 avril 2011 Statut Membre Dernière intervention 28 septembre 2015 1 339
4 août 2011 à 22:13
Bonsoir,

IN sert à déterminer si une donnée figure dans une collection.

Exemple:

SELECT * FROM ma_table WHERE jour = 'lundi' OR jour = 'mercredi'

peut se remplacer par:

SELECT * FROM ma_table WHERE jour IN('lundi','mercredi')

Un exemple plus frappant. Vous voulez isoler x communes dans une base:

SELECT * FROM ma_table WHERE code_postal IN ('75012','75013','75014','75015')

sachant que le IN(...ma collection...) peut être très long, c'est quand même plus compact que ceci:

code_postal = '75012' OR code_postal = '75013'.....

A+
0
Bon ok j'avais inversé car je suis idiot je lit en anglais au lieu de lire en sql... pardonnez moi ... lol

Bon donc la formule de base devrait etre :

WHERE monchamp IN ('%mot1%', '%mot2%");

Dans ce premier cas, est-ce que je peux utiliser les % comme avec like pour demande a ce qu'il trouve le mot parmi tous les mots ?

Ensuite est-ce que je peux faire cette même requête avec 2 champs qui cherche les mêmes mots, genre :

WHERE (monchamp1, monchamp2) IN ('%mot1%', '%mot2%");

Soyons écolo réduisons notre consommation de mots dans les requêtes sql. Ca fait des pages moins lourde et en définitive moins d'électricité consommée (wow je vais loin !) C'était la note humoristique du jour ;)

Bonne journée
0
blux Messages postés 26003 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 25 avril 2024 3 289
4 août 2011 à 22:33
Le % est en principe réservé au like, mais il faut voir ce que ton SQL est prêt à gober !
Par contre, la double recherche n'existe pas encore dans aucun SQL...
0
mpmp93 Messages postés 6652 Date d'inscription mercredi 13 avril 2011 Statut Membre Dernière intervention 28 septembre 2015 1 339
5 août 2011 à 08:46
Bjr,

CITE: ... est-ce que je peux utiliser les % comme avec like pour demande a ce qu'il trouve le mot parmi tous les mots ?

REPNSE: je n'ai pas essayé, mais peut-être ça marcherait...

CITE: ...est-ce que je peux faire cette même requête avec 2 champs qui cherche les mêmes mots, genre :
WHERE (monchamp1, monchamp2) IN ('%mot1%', '%mot2%");

REPONSE: Non, c'est ceci qu'il faudrait faire:
WHERE monchamp1 IN ('%mot1%', '%mot2%") OR monchamp2 IN ('%mot1%', '%mot2%") ;

A+
0
Suite à ce message :

=========================
Bonsoir,

IN sert à déterminer si une donnée figure dans une collection.

Exemple:

SELECT * FROM ma_table WHERE jour = 'lundi' OR jour = 'mercredi'

peut se remplacer par:

SELECT * FROM ma_table WHERE jour IN('lundi','mercredi')

Un exemple plus frappant. Vous voulez isoler x communes dans une base:

SELECT * FROM ma_table WHERE code_postal IN ('75012','75013','75014','75015')

sachant que le IN(...ma collection...) peut être très long, c'est quand même plus compact que ceci:

code_postal = '75012' OR code_postal = '75013'.....

A+
==========================

Et si le champs contient plusieurs valeur ?
Exemple :
Champ1 : 75021 75029 75220 75880 75965
Champ2 : 75029 75668 75897 75065 75884


Les deux champs contiennent 75029 et 75965, c'est fait exprès pour l'exemple.

Je veux une réponse s'il y a 75029 et 75965 dans les deux champs.
Que faire pour le faire avec un minimum de répétition dans la requête ?

Bonne journée
0
blux Messages postés 26003 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 25 avril 2024 3 289
4 août 2011 à 22:36
Ton exemple est mal posé, n'oublie pas que les champs sont testés ligne à ligne, donc 75021 de champ1sera lu en même temps que 75029 de champ2...
0
C'est bien pour cela que je pose ces question
En général j'utilise like pour faire ça mais like ne permet pas la recherche de plusieurs mots dans plusieurs champs.
Je prend un exemple que je trouve plus clair.

Champ 1 : Je pense donc je suis
Champ 2 : Je suis mais.. est ce que je pense ?

Je veux récupérer tous les réponses quand le champ et et le champ2 contiennent "suis" ET "pense"

Donc si je conclue : Impossible avec IN d'économiser des la taille de ma requête qui va finir par etre très longue a force d'ajouter des mots à chercher dans des titres, descriptions et mots clé en plus des filtres que j'ai déjà.

A moins que vous ayez une solution avec IN ou autre chose.

Bonne soirée
0
mpmp93 Messages postés 6652 Date d'inscription mercredi 13 avril 2011 Statut Membre Dernière intervention 28 septembre 2015 1 339
5 août 2011 à 08:56
Bjr,

CITE: ...mais like ne permet pas la recherche de plusieurs mots dans plusieurs champs. ...

Il faut être très prudent avec le Like. En informatique, la technique qui est à la base de tout ça s'appelle 'patern matching' (cf: Knuth - Fundamental Algorithms/ The art of Programming)

Le 'patern matching' est très chronophage. Avec 20 à 100 enregistrements, vous ne verrez quasiment aucun effet sur l'exécution de la requête. Mais il existe un seuil qui dépend de divers paramètres au-delà duquel le temps d'exécution devient exponentiel par rapport au nombre d'enregistrements. C'est pourquoi il est impératif en amont de faire une pré-sélection.

Regardez un catalogue photos, genre Picasa ou Flickr, les photos peuvent être tagguées et les utilisateurs ne peuvent chercher QUE par ces mots clés.

Un exemple, vous avez des annonces, avant de filtrer dans le descriptif, il est nécessaire de restreindre la recherche à un type d'annonces et de lieux. sans quoi la base de données s'écroule et les délais d'exécution pénalisent TOUS les autres utilisateurs. Même dans un moteur de recherche les mots sont indexés dans un système d'indexation très complexe qui allie performance (arbres binaires balancés) avec une structure similaire au système ISAM des BDD comme mySQL.

En conclusion, ne faites pas faire à votre BDD des opérations trop complexes, ça a un coût. Sur un serveur mutualisé - du genre des hébergements gratuits FREE - le nombre de requêtes est déja limité dans un temps donné, mais si en plus elles sont chronophages, il y a une limitation en nombre de requêtes simultanées.

A+
0
blux Messages postés 26003 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 25 avril 2024 3 289
5 août 2011 à 09:07
Si le principal traitement qui est fait sur ta base consiste à faire des recherches de mots dans les champs, alors il serait plus opportun de créer une table qui contient les mots-clés que tu veux rechercher.
Cette table serait alimentée à la création d'un enregistrement 'principal' et elle y serait mise en relation en n,n.
En informatique, cela veut dire créer une table d'index...
0
Je suis sur un serveur virtuel.
Je sais bien que je dois limiter les requete et ce filtrage est ce que j'ai de plus lourd.

Je limite déjà la recherche sur des critères de choix que l'utilisateur aura coché pour déterminer ce qu'il veut chercher. En espérant qu'il coche et ne laisse pas vide.

Pour mes mots clé, ces denier sont enregistrés dans la même table que ces choix. Le filtrage est toujours sauvé avant d'être appliqué, dans une insertion lié a l'utilisateur via son "user_id".

Quoi qu'il en soit je ferais des test pour voir les lenteur et au besoin ajusterai en limitant le nombre de mots par exemple.

Mon problème reste entier sur la taille des requete.
Si j'ai bien compris je ne peux pas utiliser IN comme LIKE pour chercher des mots clé dans des champs vastes. Et je ne peux pas réduire la taille des requete avec IIKE comme c'est possible avec IN.

Merci de confirmer ou d'informer.
Bonne journée
0