忘れないように記録しとこ

カバの樹

私がCodeigniterでサブクエリを使ったSQLを書くときの方法

2018年3月2日

環境

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が書けます。

若干遅くなるかもしれませんが、後々の追加修正等に対応しやすいのでおすすめです。

 

今日はこの辺でー

  • B!