Bonjour,
comme l'indique le titre, je cherche à faire une requête de ce genre :
SELECT * FROM maTable WHERE n'importeQuelChamp = 'maValeur'
En pratique, faute de mieux, je fais comme ça :
SELECT * FROM maTable WHERE champ1 = 'maValeur' OR champ2 = 'maValeur' OR ... OR champN = 'maValeur'
Existe-t-il une méthode plus générique, qui évite de faire des OR en cascade ?
Merci d'avance.
# A essayer...
Posté par Gyro Gearllose . Évalué à 3.
select * from ma_table where 'maValeur' in (champ1, champ2, champ3, champ4);
C'est du non testé, mais ça devrait rouler.
[^] # Re: A essayer...
Posté par santos . Évalué à 2.
Mais s'il y a un moyen qui évite d'énumérer les champs, je suis preneur également.
[^] # Re: A essayer...
Posté par santos . Évalué à 2.
[^] # Re: A essayer...
Posté par gaaaaaAab . Évalué à 8.
Tu peux aussi avoir une table (valeur, type, id) triée sur valeur, ou type ferait référence au type de champ, et id pointerait sur l'id de la ligne contenant ta valeur. (c'est des noms moisis, c'est juste un exemple vite torché).
Tu chercherais valeur dans cette table et le résultat de cette recherche te permettrait immédiatement d'identifier quel(s) champ(s) de quelle(s) ligne(s) contient ta valeur.
[^] # Re: A essayer...
Posté par benoar . Évalué à 3.
[^] # Re: A essayer...
Posté par guppy . Évalué à 1.
SELECT * FROM table WHERE table.champ IN ('a', 'b', 'c') OR table.champ LIKE truc%
[^] # Re: A essayer...
Posté par Gyro Gearllose . Évalué à 5.
select * from maTable where
true in (champ1 like 'maValeur%', champ2 like 'maValeur%', ...., champN like 'maValeurN');
Voilà, ça fonctionne, j'ai testé sous postgres.
C'était la minute de sql crade, juste pour le fun.
Merci pour votre attention.
# Erreur de conception ?
Posté par Obsidian . Évalué à 7.
Peux-tu nous donner une vision plus globale de ton problème ?
[^] # Re: Erreur de conception ?
Posté par santos . Évalué à 2.
côté base de données, j'ai une table ''utilisateurs'', avec des champs ''nom'', ''prenom'', ''email'', etc...
côté page web, j'ai un tableau qui affiche la liste des utilisateurs, avec tous les champs.
Mon tableau est en Ajax, il récupère la liste des utilisateurs sous forme d'un flux JSON ou XML.
Au dessus de mon tableau, j'ajoute un formulaire avec un unique champ, ''recherche rapide''.
Lors de la validation du champ, le tableau envoie le mot cherché en POST, récupère le flux contenant les résultats, et rafraîchit son contenu.
L'idée, c'est que si on tape ''François'', on obtienne des résultats tels que :
- François Nautré santos@gmail.com ...
- Claude François foo@bar.com ...
- Jean Dupont jean.dupont@francois.com ...
Du coup, pour le moment, côté serveur, je fais (version simplifiée):
SELECT * FROM table WHERE nom LIKE $_POST['recherche'] OR prenom LIKE $_POST['recherche'] OR email LIKE $_POST['recherche'] OR ...
Ça marche, mais :
1) j'ai plusieurs dizaines de champs
2) je vais devoir faire ça pour plusieurs tableaux (qui affichent des tables différentes)
Donc si le langage SQL prévoit une syntaxe pour rechercher une valeur dans n'importe quel champ d'une table, je suis preneur.
C'est plus clair comme ça ? Est-ce ma base qui est mal conçue ?
[^] # Re: Erreur de conception ?
Posté par gaaaaaAab . Évalué à 4.
C'est possible d'élaborer en rajoutant le nom de la table dans le prototype de la table précédente.
J'ai déjà vu une application résoudre ce genre de problème de cette façon, en rajoutant des tables dédiées à la recherche. Le hic, c'est qu'il faut du coup alimenter ces tables à la volée et que ça rajoute pas mal de complexité au code.
L'avantage, c'est que ça scale mieux que devoir faire une recherche multi champs multi table dans une seule grosse requête SQL monstrueuse. Tu peux aussi découper plus finement ta recherche en indexant mot par mot dans ces tables dédiées, plutôt qu'en indexant la totalité du contenu des champs.
[^] # Re: Erreur de conception ?
Posté par santos . Évalué à 2.
en rajoutant des tables dédiées à la recherche
=> j'aimerais éviter.
[^] # Re: Erreur de conception ?
Posté par Gyro Gearllose . Évalué à 4.
Pourquoi avoir choisi mysql ?
Si tu peux effictivement changer, et t'orienter vers un autre SGBD, donne au moins une chance pour quelques essais à postgresql. Il sait faire le type de recherche que tu veux, il me semble, et ce nativement (j'ai rapidement parcouru la doc, et il me semble avoir vu quelque chose là dessus http://www.postgresql.org/docs/8.4/static/textsearch.html ).
[^] # Re: Erreur de conception ?
Posté par santos . Évalué à 3.
Cependant j'ai choisi MySQL parce que :
- c'est ce que j'utilise quasi-systématiquement et que je m'en débrouille bien ;
- je sais que je n'aurai pas de souci par la suite pour héberger pour application chez un prestataire tiers ;
- pour l'application en question, MySQL est largement suffisant en termes de performances, fonctionnalités, capacité de stockage, montée en charge, etc...
De plus, toujours dans le cas présent, mon souhait de légèrement simplifier quelques requêtes de recherche ne justifie pas d'envisager un changement de SGBD.
Mais la question est tout-à-fait pertinente.
[^] # Re: Erreur de conception ?
Posté par dood . Évalué à 3.
En concaténant les champs de recherche tu peux avoir un seul champ au final (à voir quel est l'opérateur de concaténation, là c'est pour Oracle...)
SELECT * FROM table WHERE nom||prenom||email LIKE $_POST['recherche']
[^] # Re: Erreur de conception ?
Posté par eMerzh (site web personnel) . Évalué à 1.
[^] # Re: Erreur de conception ?
Posté par alouali (site web personnel) . Évalué à 2.
SELECT * FROM table WHERE nom||'#'||prenom||'#'||email LIKE $_POST['recherche']
Évidemment il ne faut pas chercher #, mais bon...
On peut aussi prégénérer un champs recherche en concaténant à chaque création ou mise à jour des champs correspondant : ça évite de refaire les concaténations à chaque recherche. On perd un peu en place place, mais on gagne en performances.
[^] # Re: Erreur de conception ?
Posté par santos . Évalué à 2.
C'est vrai que c'est nettement plus propre que ce que je faisais au départ.
[^] # Re: Erreur de conception ?
Posté par gaaaaaAab . Évalué à 6.
[^] # Re: Erreur de conception ?
Posté par benoar . Évalué à 4.
[^] # Re: Erreur de conception ?
Posté par santos . Évalué à 4.
En même temps, MySQL permet bien de consulter et éditer la structure d'une table (SHOW COLUMNS, ALTER TABLE, toussa...)
[^] # Re: Erreur de conception ?
Posté par benoar . Évalué à 2.
Pour faire une analogie avec les langages de programmation, si tu veux appeler toutes les méthodes d'un objet en Java (par exemple), tu ne pourra pas "de base". Il faudra utiliser les fonctions de méta-programmation.
[^] # Re: Erreur de conception ?
Posté par Croconux . Évalué à 2.
J'espère au moins que dans le vrai code les valeurs passées sont un minimum protégées parce que la porte ouverte à toutes les injections SQL...
[^] # Re: Erreur de conception ?
Posté par santos . Évalué à 2.
C'est un exemple ultra minimal et symbolique (une variable PHP au milieu d'une requête SQL...)
[^] # Re: Erreur de conception ?
Posté par santos . Évalué à 4.
Ça me permet d'ajouter un utilisateur ou de faire les sauvegardes directement à partir du champ de recherche ;-)
[^] # Re: Erreur de conception ?
Posté par BAud (site web personnel) . Évalué à 2.
[^] # Re: Erreur de conception ?
Posté par JoeltheLion (site web personnel) . Évalué à 0.
Au dessus de mon tableau, j'ajoute un formulaire avec un unique champ, ''recherche rapide''.
Lors de la validation du champ, le tableau envoie le mot cherché en POST, récupère le flux contenant les résultats, et rafraîchit son contenu.
Je dis peut-être une bêtise, mais tu pourrais pas faire la recherche côté client, en javascript?
# recherche plein texte
Posté par BAud (site web personnel) . Évalué à 9.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
(bon ça n'a l'air de fonctionner qu'en MyISAM :/ mais ça a peut-être évolué depuis).
C'est au niveau de la table que tu spécifies FULLTEXT, ce qui indexera les champs significatifs.
Tu peux aussi utiliser une vraie base de données relationnelle avec PostgreSQL pour le faire
http://www.postgresql.org/docs/8.3/static/textsearch.html
[^] # Re: recherche plein texte
Posté par santos . Évalué à 2.
Par contre :
MATCH (col1,col2,...) AGAINST (expr [search_modifier])
il faut tout de même préciser le nom des colonnes, donc ça ne résout pas mon problème initial.
[^] # Re: recherche plein texte
Posté par NeoX . Évalué à 2.
[^] # Re: recherche plein texte
Posté par BAud (site web personnel) . Évalué à 3.
Peut-être demander à ce que ça soit fait au niveau d'une vue plutôt qu'au niveau table pour différencier les utilisations, 'fin j'élabore. L'idée c'est que ça puisse être géré au niveau du dictionnaire de données plutôt que dans chacune des requêtes, le besoin me paraît clair.
Pour que cette demande d'évolution soit prise en compte, il risque de falloir demander à un développeur spécialiste de la recherche fulltext de la relire pour en profiter pour lui expliquer en direct ;-)
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.