[CodeIgniter2] アクティブレコードで複雑なWHERE句を生成する

公開
更新日

スポンサーリンク

既に動いているウェブアプリの改良やメンテナンスでCodeIgniterを使い続けています。

Laravel PHPに心惹かれているのですが、移行は簡単には出来ないですしね。CodeIgniterで作ったものは、メンテナンスに限界がくるまではCodeIgniterで動かし続けることになるでしょう。

さてCodeIgniterのアクティブレコードはとても便利なのですが、複雑なWHERE句を作るとなると、良い方法がなかなか見つからなかったりします。

例えば以下のようなSQL文を実行したい時。

SELECT * FROM table WHERE a = 'foo' AND ( b LIKE '%bar%' AND b LIKE '%hoge%' );

カラムaがfooで、なおかつカラムbにbarかhogeが含まれるレコードを検索したいという時に、これをアクティブレコードで以下のように書くとうまくいきません。

$this->db
  ->from('table')
  ->where('a', 'foo')
  ->like('b', 'bar')
  ->or_like('b', 'hoge');

//生成されるSQL文
//SELECT * FROM table WHERE a = 'foo' AND b LIKE '%bar%' OR b LIKE '%hoge%';

初めのOR_LIKEメソッドで生成されるコードがカッコで囲まれないので、検索結果が「aがfooかつbにbarが含まれているもの、又はbにhogeが含まれているもの」になってしまいます。ではどうするか。

こういうのは公式マニュアルのwhereメソッドの使い方の4番目にある「自由に指定できる文字列を使用する方法」を使うとうまくいきます。要するにWHERE句の中身を自分で好きなように書くわけですね。

$this->db
  ->from('table')
  ->where('a', 'foo')
  ->where("('b' LIKE '%bar%' OR 'b' LIKE '%hoge%')");

//生成されるSQL文
//SELECT * FROM table WHERE a = 'foo' AND (b LIKE '%bar%' OR b LIKE '%hoge%');

上記の例の場合、以下の書き方でも大丈夫です。

$this->db
  ->from('table')
  ->where("'a' = 'foo' AND ('b' LIKE '%bar%' OR 'b' LIKE '%hoge%')");

//生成されるSQL文
//SELECT * FROM table WHERE a = 'foo' AND (b LIKE '%bar%' OR b LIKE '%hoge%');

ということで、入り組んだ条件のSQL文を書く時は、WHERE句の中身は自分で書いてしまえばいいという話でした。

スポンサーリンク


Comment