目次
環境
Codeigniter : 3.1.7
はじめに
CodeigniterにはQuery Builderがあり、ある程度の事は対応することができます。
しかし下記のようなものに上手く対応できません。
SELECT * FROM table1 WHERE flg = 1 AND ( access1 LIKE '%A%' OR access2 LIKE '%A%' OR access3 LIKE '%A%' )
お判りでしょうか?
例えば店舗を探す時に、
公開フラグ(flg )が1で、
アクセス情報(access)のどこかに検索対象の文字が存在している店舗を探すとします。
その場合、$this->db->or_like()
などを使うと下記SQLになってしまいます。
SELECT * FROM table1 WHERE flg = 1 OR access1 LIKE '%A%' OR access2 LIKE '%A%' OR access3 LIKE '%A%'
これですと、公開フラグ(flg )が0の店舗も引っかかってしまいますし、
検索条件が無くても、公開フラグ(flg )が1なら引っかかります。
力技でやる方法もありますが・・・
$esc_str = $this->db->escape_like_str('A'); $this->db->where("WHERE flg = 1 AND (access1 LIKE '%{$esc_str}%' ESCAPE '!' OR access2 LIKE '%{$esc_str}%' ESCAPE '!' OR access3 LIKE '%{$esc_str}%' ESCAPE '!' )", NULL, FALSE);
正直キツイっす・・・
サブクエリを使う
私はQuery Builderで対応できない状況にぶち当たった時、サブクエリで対応してます。
Query Builderを使用しつつサブクエリを取得するには以下のようなやり方をします。
// 読み込み $subquery_init = $this->load->database('', TRUE); $subQuery = $subquery_init->select('no', FALSE) ->from('table') ->or_like(array( 'access1' => 'A', 'access2' => 'A', 'access3' => 'A' )) ->get_compiled_select(); // 初期化 $subquery_init->reset_query();
上記で作ったサブクエリを利用して
$this->db->where("no IN {$subQuery}", NULL , FALSE);
みたいな形でSQLが書けます。
若干遅くなるかもしれませんが、後々の追加修正等に対応しやすいのでおすすめです。
今日はこの辺でー