下記のSQL文は間違っておりますでしょうか?

実行すると返事が無いまま固まってしまいます。

(1)
SELECT count(*) FROM table1 t1 INNER JOIN table2 t2 ON t1.co=t2.co WHERE t1.* LIKE '%テスト%'

(2)
SELECT t1.*,t2.ccc,t2.ddd FROM table1 t1 INNER JOIN table2 t2 ON t1.co=t2.co
WHERE concat(t1.aaa,t1.bbb,t2.ccc) LIKE '%テスト%'
AND concat(t1.aaa,t1.bbb,t2.ccc) LIKE '%テスト2%'

MySQL 4.x です。

よろしくお願いします。

回答の条件
  • 1人2回まで
  • 登録:2008/01/15 12:04:06
  • 終了:2008/01/16 16:11:24

回答(2件)

id:riatan No.1

riatan回答回数11ベストアンサー獲得回数02008/01/15 12:23:57

ポイント20pt

今構文チェックができる状態にないのでちょっと自信がないですが、

「WHERE t1.* LIKE '%テスト%'」これは構文的にありなのでしょうか・・?

列を明示的に指定しなければいけないと思ったのですが、違っていたらごめんなさい。

あと、エラーがでないで返事がないというのは

単に重くて固まっている可能性もあるのではないかと思います。

%テスト% というLIKEの文を使うと、

インデックスが使えないので非常にコストがかかる検索方法になります。

データ量が多いのでしたら、これが原因かもしれません。

id:worldtravel

ありがとうございます。

「%テスト%」は、例えば住所に「xxx市を含む行を検索」としたいので

どうしても使わなければなりません。

他の回答も待ってみます。

2008/01/15 13:05:15
id:chuken_kenkou No.2

chuken_kenkou回答回数722ベストアンサー獲得回数542008/01/15 17:13:58

ポイント80pt

WHERE t1.* LIKE '%テスト%'

「t1.*」を条件に使うような構文はありません。

WHERE t1.列名1 LIKE 'パターン文字列'
      OR t1.列名2 LIKE 'パターン文字列'
      OR t1.列名3 LIKE 'パターン文字列'

のように指定する必要があります。

また、「列名 LIKE '%テスト%'」といった検索条件は、仮にインデクスがあっても有効利用されません。

「concat(t1.aaa,t1.bbb,t2.ccc)」のように、列の結合など、加工したものを条件指定する場合も、仮にインデクスがあっても有効利用できません。

つまり、母体件数が増えれば増えるほど、性能劣化します。

また、単純に「concat(t1.aaa,t1.bbb,t2.ccc)」のように列連結すると、区切りがないので、意図したデータ以外もヒットしてしまいます。


「%テスト%」は、例えば住所に「xxx市を含む行を検索」としたいので

どうしても使わなければなりません。

列を都道府県、市区郡、町名などで分けて構成しておけば、少なくとも「列名 LIKE 'xxx%'」のような前方一致にできるのでは?

全文検索のような使い方をしたいなら、MoSQLを利用することも検討してみてください。

id:worldtravel

ありがとうございます。

色々と勉強になる事を沢山教えていただきありがとうございました。

> 単純に「concat(t1.aaa,t1.bbb,t2.ccc)」のように列連結すると、区切りがないので、意図したデータ以外もヒットしてしまいます。

間にスペースなどを入れるにはどうすれば良いのでしょうか。

concat(t1.aaa,' ',t1.bbb,' ',t2.ccc)

こんな感じですか。

また、t1.aaa、t1.bbb、t1.ccc、t1.ddd.....と、沢山の項目から検索したい場合、

concat(t1.aaa,t1.bbb,t2.ccc)と言う様にするのと、

WHERE t1.列名1 LIKE 'パターン文字列'

OR t1.列名2 LIKE 'パターン文字列'

OR t1.列名3 LIKE 'パターン文字列'

というようにするのでは、一般的にはどちらが良い。と言うような事はあるのでしょうか。

2008/01/15 17:34:13
  • id:b-wind
    構文は間違ってないけど速度は遅そうですね。
    SQL 自体が間違っているとその場でエラーを出すのですぐにわかります。
    単純に処理が重くて出力に時間がかかっているだけだと思われます。
  • id:worldtravel
    ありがとうございます。

    phpMyadminでテストすると下記の様にエラーになります。
    (実際のコードです)
    どこかダメなのでしょうか....

    エラー

    実行した SQL: ドキュメント

    SELECT count( * )
    FROM Shouhin t1
    INNER JOIN Honsha t2 ON t1.code_company = t2.code_company
    WHERE t1 . * LIKE '%テスト%'

    MySQLのメッセージ: ドキュメント
    #1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '* LIKE '%\Æ\?\È%'' at line 1
  • id:chuken_kenkou
    >間にスペースなどを入れるにはどうすれば良いのでしょうか。
    >concat(t1.aaa,' ',t1.bbb,' ',t2.ccc)
    >こんな感じですか。

    空白よりは、0x0000など存在し得ないコードを入れる方がいいでしょう。

    concat(t1.aaa,0x0000,t1.bbb,0x0000,t2.ccc)

    という書き方でもいいですし、

    concat_ws(0x0000,t1.aaa,t1.bbb,t2.ccc)

    といった書き方もできます。

    >また、t1.aaa、t1.bbb、t1.ccc、t1.ddd.....と、沢山の項目から検索したい場合、
    >concat(t1.aaa,t1.bbb,t2.ccc)と言う様にするのと、
    >WHERE t1.列名1 LIKE 'パターン文字列'
    >OR t1.列名2 LIKE 'パターン文字列'
    >OR t1.列名3 LIKE 'パターン文字列'
    >というようにするのでは、一般的にはどちらが良い。と言うような事はあるのでしょうか。

    まず、パターン文字列が、'xxx%'という前方一致などでないと、インデクスを有効利用できません。

    concat(t1,aaa,t1.bbb,t1.ccc) like 'xxx%'

    前方一致のパターンであっても、列を結合してしまうと、仮にaaa、bbb、cccの各列にそれぞれ
    インデクスがあっても、RDBMS側は利用してくれません。

    面倒でも

    t1.aaa like 'xxx%'
    or t1.bbb like 'xxx%'
    or t1.ccc like 'xxx%'

    のように指定すれば、aaa、bbb、cccの各列にそれぞれインデクスがあれば、利用可能です。

    MySQLでは未実装だと思いますが、他のRDBMSでは以下のようなことが可能な場合もあります。

    (1)RDBMSやバージョンによって、前方一致のような絞込みはできなくても、母体サーチよりは
     インデクス最下段サーチの方が早いと判断され、インデクスを使うものもある。

    (2)RDBMSやバージョンによっては、式の結果でインデクスを定義できるものもある。
     今回のようなケースでは、aaa~ccc列を区切りコードを含めた結合した式で予めインデクスを
     定義するといった方法を取る。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません