MySQL-すべての列の値を確認する方法


11

知りたいのですが、すべての列で特定の値を検索する良い方法はありますか?私の目的では、それはまったく高速である必要はありません。これは1回限りの処理であり、すべてのフィールド名を入力する必要は本当にありません。それがまさに今私がやろうとしていることですが、確かにもっと良い方法があると思います。

私はこれを回したいと思います:

SELECT * FROM table WHERE col1 = 'val' OR col2 = 'val' OR col3 = 'val';

これに:

SELECT * FROM table WHERE * = 'val'

...または、さらに良い(私はそれを真剣に疑っていますが...)

SELECT * FROM table WHERE * like '%val%'

私はこれを見つけましたが、これは少し近いとは思えませんが、近くには何も見つかりません:

SELECT whatever WHERE col1,col2 IN ((val1, val2), (val1, val2), ...)

違いは、指定された値の列を選択して検索するのに対し、すべての列で単一の値を検索しようとしていることです。

それは重要ではありませんが、私が興味があるのは何よりも言ったように

回答:


23

SQLは、同じドメイン内に値を持つ可能性のある N個の列を持つことはおそらく良いテーブル設計ではないため、これを行う良い方法を提供しません。これは潜在的にあなたが列を持っている場合のような「繰り返しグループ」の場合でphone1phone2phone3、... phoneN

値の論理ドメインが同じ列が複数ある場合は、それが多値属性(電話の例など)である場合があります。複数の値を持つ属性を格納する標準的な方法は、別のテーブルの複数の行として、プライマリテーブルの属性が属する行への参照を使用することです。

その場合、従属テーブルの1つの列で特定の値を検索するだけで済みます。

SELECT t.* FROM mytable AS t
JOIN phones AS p ON t.primaryKey = p.refKey 
WHERE p.phone = ?

1
また、何らかの理由でテーブルレイアウトを変更できない場合は、この形式でデータを表すビューを記述してから、ビューにクエリを実行できます。
CodeCaster

10
いいえ、テーブルのレイアウトを変更するだけです。それでおしまい。「変えられない」という言い訳に飽きた。私はそれをもう受け入れません。物事を変える方法を学ぶ時が来ました。
ビルカーウィン、

15

あなたが得ることができるより近いものはこれを使っていINます:

SELECT * FROM table WHERE 'val' IN (col1, col2, ..., colN) ;

チェックするすべての列を書き込む必要があります。
そして、それはORあなたが持っている表現と違いはなく、パフォーマンスやその他の点でも同じです。これは、少し少ない文字数で、式を記述するための別の同等の方法です。


3

2つのステップでそれを行う必要があります。最初にsqlを生成します(スキーマSでテーブルの名前がTであると仮定します:

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');

これで、この文字列を実行できます。'a'を余分な 'で引用する必要があることに注意してください。これをプロシージャなどに入れると、生成された文字列を準備して実行できます。

私はテストしました:

create table t (a char(3), b varchar(5), c int);
insert into t(a,b) values ('a','b'),('b','c'),('c','c');    

生成されたクエリ:

SELECT * FROM t WHERE 'a' in (a,b)

そしてそれを実行すると次の結果になります:

a   b   c
---------
a   b   

1

質問してから1年になったような気がしますが、私が探していたものと思われるものに出くわしました。これは、私が予想していたようなSQLステートメントではありませんが、私が望んでいたことを実行します。

MySQL Workbenchでは、テーブルまたはスキーマを右クリックし、[テーブルデータの検索]を選択できます。スキーマコンテキストメニュー


0

これを試してください:

select
    *
from
    _table_
where
    concat('.', col1, '.', col2, '.', col3, '.') like "%.search_value.%";

これは.、検索文字列にがないことを前提としています。保証できない場合は、別の「区切り文字」を使用できます。


1
ソリューションが機能する理由を説明していただけますか?コードのみの回答は、ここでは適切な回答とは見なされません。
George.Palacios

動作しません。例えばTE検索が含まれている場合%_、または任意の列が含まれている.
Jasen

1
@Jasen特殊文字をエスケープして、別の区切り文字を使用できます。
Anon0012398193

@ George.Palacios-あなたが不明確だと思うことは何ですか?
Anon0012398193

正しいセパレータを選択するのは非常に難しい場合があります。このアプローチを正しく行うのは非常に難しい
Jasen

0

最も簡単な解決策は

mysqldump ... --skip-extended-insert db table | grep 'val'

valがSQL構文で一般的に発生するものでない限り、


代替案はあなたがこれが役立つだろうと思ったということなので、あなたが私をあざけっているといいのですが。
donutguy640

1
私は間違いなくそうではありません。これは、db / tableの「どこ」にあるかわからない場合に有効な方法です。grepは、値が存在する行全体(テーブル名を含む)を返します。これはSQLではなく、プログラムで出力を処理する場合にはあまり役に立ちませんが、シンプルで非常に高速です。
jkavalik

-2

これを試して。

SELECT *
FROM table
WHERE CONCAT(col1,' ',col2,' ',col3)="val val val";

CONCAT()を使用してここと同じように列の値を区切ると、列をスペースで区切って関数内でより適切な結果を指定でき、値もスペースで区切られた文字列をチェックして、結果を確認できます。


-3

これは、information_schemaデータベースを使用することで可能です。基本的には、特定のテーブルのすべての列をリストし、GROUP_CONCATを使用してそれらを1行としてリストし、INステートメントでフィードします。

select * from db.table where 'value' in (select GROUP_CONCAT(COLUMN_NAME) from INFORMATION_SCHEMA.columns where table_schema = 'db' and table_name = 'table');

これは、すべての列に「値」が存在する場合にのみ行を返します。


1
もしかしてif 'value' is present in any of the columns?さらに、次のような文字列型の述語を追加できます: `and DATA_TYPE IN( 'char'、 'varchar')`
Lennart

1
これにより、OPの目的である、列に明示的に名前を付けることを回避できます。これはワイルドカードではありませんが、情報スキーマに対するGROUP_CONCATは、すべての列名のワイルドカードと同じくらい優れています。
tbrookside

2
これを機能させるのに苦労しています。dbとtableを自分のスキーマとテーブル名で置き換えましたが、実際の名前のプレースホルダーとして意図されているものは他にありますか?また、内部ステートメントを単独で試してみたところ、行のデータではなく列名がCONCATであることがわかりました。それはあなたが意図したことですか?
donutguy640

4
当然のことながら、これは誤りです。クエリでは、「値」を内容ではなく列の名前と比較します。私はこれに反対票を与えなければなりません。
ビルカーウィン

4
より正確には、これは文字列「値」を、列名のコンマ区切りのリストである文字列と比較します-本質的にと同じwhere 'value' in ('col1,col2,col3…')です。
Andriy M
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.