Je suis curieux, existe-t-il un bon moyen de rechercher toutes les colonnes pour une valeur donnée? Pour mes besoins, il n'a pas besoin d'être rapide du tout, c'est juste une chose unitaire, et je ne veux pas vraiment avoir à taper chaque nom de champ. C'est précisément ce que je vais faire pour l'instant, mais je pense qu'il y a sûrement une meilleure façon.
Je voudrais tourner ceci:
SELECT * FROM table WHERE col1 = 'val' OR col2 = 'val' OR col3 = 'val';
en cela:
SELECT * FROM table WHERE * = 'val'
... ou encore mieux (même si j'en doute sérieusement ...)
SELECT * FROM table WHERE * like '%val%'
J'ai trouvé this , ce qui semble un peu proche, mais je ne trouve rien de plus proche:
SELECT whatever WHERE col1,col2 IN ((val1, val2), (val1, val2), ...)
La différence étant, qui recherche une sélection de colonnes pour les valeurs spécifiées, alors que j'essaie de rechercher TOUTES les colonnes pour une seule valeur.
Ce n'est pas important cependant, comme je l'ai dit plus que tout, je suis juste curieux
On dirait que ça fait un an que j'ai posé cette question, mais je suis juste tombé sur ce qui semble être exactement la chose que je cherchais! Ce n'est pas une instruction SQL, comme je l'avais prévu, mais elle fait ce que je voulais.
Dans MySQL Workbench, vous pouvez cliquer avec le bouton droit sur la table ou le schéma et choisir Rechercher les données de la table .
SQL ne fournit pas un bon moyen de le faire, car ce n'est probablement pas une bonne conception de table d'avoir N colonnes qui pourrait ont des valeurs dans le même domaine. C'est potentiellement un cas de "groupes répétitifs" comme si vous avez des colonnes phone1
, phone2
, phone3
, ... phoneN
.
Si vous avez un certain nombre de colonnes qui ont le même domaine logique de valeurs, il peut s'agir d'un cas où il s'agit d'un attribut à valeurs multiples (comme l'exemple des téléphones). La méthode standard de stockage des attributs à valeurs multiples consiste en plusieurs lignes dans une autre table, avec une référence à la ligne à laquelle elles appartiennent dans la table principale.
Si vous le faites, il vous suffit de rechercher la valeur spécifique dans une colonne de la table dépendante.
SELECT t.* FROM mytable AS t
JOIN phones AS p ON t.primaryKey = p.refKey
WHERE p.phone = ?
Plus vous vous rapprochez, utilisez IN
:
SELECT * FROM table WHERE 'val' IN (col1, col2, ..., colN) ;
Vous devez encore écrire toutes les colonnes que vous souhaitez vérifier.
Et ce n'est pas différent de l'expression OR
que vous avez, pas en performance ou autrement. C'est juste une manière différente et équivalente d'écrire l'expression, avec un peu moins de caractères.
Vous devez le faire en deux étapes, générez d'abord le SQL comme (en supposant que votre table est nommée T dans le schéma S:
select concat(' SELECT * FROM t WHERE ''a'' in ('
, GROUP_CONCAT(COLUMN_NAME)
, ')')
from INFORMATION_SCHEMA.columns
where table_schema = 's'
and table_name = 't'
and DATA_TYPE IN ('char','varchar');
Vous pouvez maintenant exécuter cette chaîne. Notez que vous devez citer le "a" avec un supplément ". Si vous mettez cela par exemple dans une procédure, vous pouvez préparer et exécuter la chaîne qui a été générée.
J'ai testé avec:
create table t (a char(3), b varchar(5), c int);
insert into t(a,b) values ('a','b'),('b','c'),('c','c');
La requête générée où:
SELECT * FROM t WHERE 'a' in (a,b)
et une exécution qui se traduit par:
a b c
---------
a b
Essaye celui-là:
select
*
from
_table_
where
concat('.', col1, '.', col2, '.', col3, '.') like "%.search_value.%";
Cela suppose qu'il n'y a pas de .
dans votre chaîne de recherche. Si vous ne pouvez pas garantir cela, vous pouvez peut-être utiliser un "caractère de séparation" différent.
La solution la plus simple consiste à
mysqldump ... --skip-extended-insert db table | grep 'val'
Sauf si val est quelque chose qui est une occurrence courante dans la syntaxe sql.