ユーザーが選択できる「オプション」が正確に5つあることを考えると、静的SQLステートメントを選択します。
私がすることは、特定のオプションの「制限なし」を表す値として空の文字列を使用することです。したがって、私のステートメントは次のようになります。
HAVING `values` LIKE CONCAT('%',:b1,'%')
AND `values` LIKE CONCAT('%',:b2,'%')
AND `values` LIKE CONCAT('%',:b3,'%')
AND `values` LIKE CONCAT('%',:b4,'%')
AND `values` LIKE CONCAT('%',:b5,'%')
オプション1と2にのみ制限を適用し、オプション3には制限を適用しない場合。
$sth->bind_param(':b1','Red');
$sth->bind_param(':b2','Wood');
$sth->bind_param(':b3','');
$sth->bind_param(':b4','');
$sth->bind_param(':b5','');
オプション2にのみ制限を適用するには、たとえば
$sth->bind_param(':b1','');
$sth->bind_param(':b2','Wood');
$sth->bind_param(':b3','');
$sth->bind_param(':b4','');
$sth->bind_param(':b5','');
これにより、静的ステートメントを使用できます。変更する必要があるのは、バインドパラメーターに指定された値だけです。
オプションの「制限なし」を表すためにNULL値を使用することもできますが、NULL値が指定された場合に「制限なし」を実行するようにSQLステートメントを変更する必要があります。特にNULL値を確認してください。例:
HAVING ( `values` LIKE CONCAT('%',:b1,'%') OR :b1 IS NULL )
AND ( `values` LIKE CONCAT('%',:b2,'%') OR :b2 IS NULL )
AND ( `values` LIKE CONCAT('%',:b3,'%') OR :b3 IS NULL )
-または-LIKE述部で使用するために、NULLを空の文字列に変換します。
HAVING `values` LIKE CONCAT('%',IFNULL(:b1,''),'%')
AND `values` LIKE CONCAT('%',IFNULL(:b2,''),'%')
AND `values` LIKE CONCAT('%',IFNULL(:b3,''),'%')
同じ手法がWHERE句でも機能します。あなたの場合、WHERE句がより適切であるかどうかを検討することをお勧めします。(提供された情報からはわかりません。)
ただし、HAVING句は、ステートメントに含まれる行を制限しないことに注意してください。むしろ、HAVING句は、結果セットから返される行のみを制限します。HAVING句は、実行プランのほぼ最後に適用されます(その後に、ORDERBYとLIMITのみが続くと思います。
HAVING句は集計に適用できますが、WHERE句では適用できません。HAVING句は、WHERE句では実行できないSELECTリストの列を参照できます。
(また、VALUESは予約語であり、修飾されていない場合は注意してください(前にalias.
、が付いている場合は、バッククォートで囲む必要がある場合があります)。