MySQLでのOR検索やAND検索(あいまい検索)

まず最初に頭に入れておく事

AND検索は、「2つ以上の文字列が両方とも一致しないと検索しない」

OR検索は、「2つ以上の文字列のうち どれかが一致すれば検索する」

PDOを使用してあいまい検索(LIKE)する場合の注意点

PDOでLIKEを使う場合は、最初のSQL文発行のときに 下記のように LIKE %文字列% と書いてはいけません!

PDOで LIKE %文字列%を使う場合の間違った例
$st = $pdo->prepare("SELECT * FROM table WHERE column LIKE %kensaku%");

正しくは 下記のようにします
バインドしない方法
$st = $pdo->prepare("SELECT * FROM table WHERE column LIKE ?");
$st->execute(array("%$kensaku%"));

バインドするやり方
$kensaku = '%'.$kensaku.'%';
$st = $pdo->prepare("SELECT * FROM table WHERE column LIKE :kensaku");
$st->bindParam(':kensaku',$kensaku);
$st->execute();

AND検索 や OR検索を使う場合のSQL文(PDO)

AND検索やOR検索のSQL文は次のようになります。(キーワードが2つの場合)

//最初に文字列を空スペースでexplode関数で分解し配列に代入しておきます(やり方は後で説明)
$kensaku0 = '%'.$kensaku[0].'%';
$kensaku1 = '%'.$kensaku[1].'%';
$st = $pdo->prepare("SELECT * FROM table WHERE column LIKE :kensaku0 column LIKE :kensaku1");
$st->bindParam(':kensaku0',$kensaku0);
$st->bindParam(':kensaku1',$kensaku1);
$st->execute();

まずはスペースで区切られたワードを配列に入れよう

まず始めにすることは、POSTやらGETで来たワードをスペースで分解し、配列に入れてやる事です

注意しないといけないことは、and検索やor検索 だけでなく、普通に1ワードで検索してきた時の処理も忘れてはいけないということです

$kensaku = htmlspecialchars($_POST['kensaku']);//検索されたワードを$kensakuに代入

$kensaku = trim($kensaku);//検索されたワードの前後スペースのみ削除しておく

$kensaku = str_replace(" "," ",$kensaku);//全角スペースがあれば、半角スペースに変換

if(stristr($kensaku, " ")){//もし半角スペースが間にあれば検索文字列を分解する
$word = explode(" ", $kensaku);
$count = count($word);//配列の数をカウントしておく
}

以上が検索キーワード分解の流れです

PDOで AND検索 OR検索 LIKE句を使用する

OR検索をPDOを使用してやってみます
下記の例では、[tableテーブル] の [clumnカラム] の中から検索するというソースです

//検索文字列を$kensakuに代入
$kensaku = htmlspecialchars($_POST['kensaku']);
//OR検索
$query = 'SELECT * FROM table WHERE';//クエリ文の前半作成
if($kensaku){
$count = 1;//カウントを1にしておく
$kensaku = trim($kensaku);//検索文字列の前後の空スペースだけを除去
$kensaku = str_replace(" "," ",$kensaku);//全角スペースがあれば、半角スペースに変換
if(stristr($kensaku, " ")){//複数キーワードでの検索
$word = explode(" ", $kensaku);//検索ワードをスペースで分割して配列に格納
$count = count($word);//配列の数を数えている
//空スペースで区切られた数によってSQL文を組み立てる
for($i=0; $i<$count; $i++){//配列の数だけ繰り返す
if($i!="0"){
$sql = $sql." OR";
}
$sql = $sql." column LIKE :kensaku".$i;
}
}
}else{
$count = 0;
}
$query = $query.$sql;//OR検索した時のSQL文
//ここから検索結果
if($kensaku <> ""){//検索窓が空なら検索しない
//単ワードでの検索の時
if($count == 1){
$kensaku2 = '%'.$kensaku.'%';//単ワードの時の検索文字列を%検索文字%にした。
$stmt = $pdo->prepare("SELECT * FROM table WHERE column LIKE :kensaku");
$stmt->bindParam(':kensaku',$kensaku2);
$stmt->execute();
}
//OR検索の場合
elseif($count > 1){
$stmt = $pdo->prepare($query);
for($i = 0; $i <$count; $i++) {//検索ワードの数だけ繰り返す
$word2[$i] = '%'.$word[$i].'%';//検索ワード1つ1つを%検索文字列%に変換
$holder = ':kensaku'.$i;//ホルダー用
$stmt->bindParam($holder,$word2[$i]);
}
$stmt->execute();
}
//OR検索終り(以下 while文につづく)

Notice: Undefined offset: 49 in /home/member/sitemix_55218/site/or_kensaku.php on line 60