このエントリーをはてなブックマークに追加

更新日: 2016年2月25日

実行時間: 0.0222

Active Record (読込み処理) Part 2

 Active Record (読込み処理) Part 1では、基本的なデータ参照の方法を解説 していきましたが、この項では、データ参照のためのより複雑な条件句の生成方法を解説していきます。

 また、論理演算子の優先順位について、CodeIgniterのActiveRecodeにおける注意点を説明しています。

検索条件

 Active Record (読込み処理) Part 1で紹介した「where()」メソッド以外の 検索条件の指定方法を
解説いたします。

or_where($key, $value = NULL, $escape = TRUE)

「where()」メソッドは、複数の条件を指定する際に「AND」で結んでいきましたが、 このメソッドは「OR」で結んでいきます。

「where()」メソッド同様、第一引数にフィールド名、第二引数に「値」を指定することができます。 複数回「or_where()」メソッドをコールすることで、「OR」で連結されていきます。

    $this->db->or_where('id', 3);
    $this->db->or_where('id', 5);
    $this->db->or_where('id', 7);

    上記のコードが実行されるとデータベースオブジェクトに、下記のSQLクエリの一部がキャッシュされます。

    `id` = 3 OR `id` = 5 OR `id` = 7

または、連想配列を引数に指定することで1度に複数のOR条件を指定することができます。

    $where = array(
        'id' => 3,
        'id' => 5,
        'id' => 7,
    );
    $this->db->or_where($where);

    上記のコードが実行されるとデータベースオブジェクトに、下記のSQLクエリの一部がキャッシュされます。

    `id` = 3 OR `id` = 5 OR `id` = 7

where_in($key = NULL, $values = NULL)

 「IN」演算子を用いた条件句を生成します。

 第一引数にフィールド名を指定し、第二引数に1つ以上の値を持つ配列を指定します。

    $this->db->where('age <', 20);
    $in = array(
        'A',
        'B',
        'X',
    );
    $this->db->where_in('team', $in);

    上記のコードが実行されるとデータベースオブジェクトに、下記のSQLクエリの一部がキャッシュされます。

    `age` < 20 AND `team` IN ('A', 'B', 'X')

or_where_in($key = NULL, $values = NULL) 一番上に戻る

 「where_in()」メソッドは、「AND」で条件句を連結しますが、このメソッドは「OR」で連結していきます。

    $this->db->where('age <', 20);
    $in = array(
        'A',
        'B',
        'X',
    );
    $this->db->or_where_in('team', $in);

    上記のコードが実行されるとデータベースオブジェクトに、下記のSQLクエリの一部がキャッシュされます。

    `age` < 20 OR `team` IN ('A', 'B', 'X')

where_not_in($key = NULL, $values = NULL) 一番上に戻る

 「NOT IN」演算子を用いた条件句を生成します。

 第一引数にフィールド名を指定し、第二引数に1つ以上の値を持つ配列を指定します。

    $this->db->where('age <', 20);
    $in = array(
        'A',
        'B',
        'X',
    );
    $this->db->where_not_in('team', $in);

    上記のコードが実行されるとデータベースオブジェクトに、下記のSQLクエリの一部がキャッシュされます。

    `age` < 20 AND `team` NOT IN ('A', 'B', 'X')

or_where_not_in($key = NULL, $values = NULL) 一番上に戻る

 「where_not_in()」メソッドは、「AND」で条件句を連結しますが、このメソッドは「OR」で連結していきます。

    $this->db->where('age <', 20);
    $in = array(
        'A',
        'B',
        'X',
    );
    $this->db->or_where_not_in('team', $in);

    上記のコードが実行されるとデータベースオブジェクトに、下記のSQLクエリの一部がキャッシュされます。

    `age` < 20 OR `team` NOT IN ('A', 'B', 'X')

like($field, $match = '', $side = 'both') 一番上に戻る

 「LIKE」演算子を用いた条件句を生成します。

 第一引数にフィールド名、第二引数にマッチさせる文字列を指定します。
 第三引数には、「both」「before」「after」のいずれかの文字列を指定します。
 デフォルトは「both」です。

    • both : マッチ文字列の両サイドに「%」文字を付加します。
    • before : マッチ文字列の前に「%」文字を付加します。
    • after : マッチ文字列の後に「%」文字を付加します。
  • both
  • $this->db->like('service_code', 'hoge');
    `service_code` LIKE '%hoge%'
  • before
  • $this->db->like('service_code', 'hoge', 'before');
    `service_code` LIKE '%hoge'
  • after
  • $this->db->like('service_code', 'hoge', 'after');
    `service_code` LIKE 'hoge%'

 第一引数にフィールドには、連想配列で複数の条件を指定することも可能です。
 第二引数に値を指定する必要はありません。

  • both
  • $like = array(
        'service_code' => 'hoge',
        'shop_name' => 'foo',
    );
    $this->db->like($like);
    `service_code` LIKE '%hoge%' AND `shop_name` LIKE '%foo%'
  • before
  • $like = array(
        'service_code' => 'hoge',
        'shop_name' => 'foo',
    );
    $this->db->like($like, , 'before');
    `service_code` LIKE '%hoge' AND `shop_name` LIKE '%foo'
  • after
  • $like = array(
        'service_code' => 'hoge',
        'shop_name' => 'foo',
    );
    $this->db->like($like, , 'after');
    `service_code` LIKE 'hoge%' AND `shop_name` LIKE 'foo%'

not_like($field, $match = '', $side = 'both') 一番上に戻る

 「NOT LIKE」演算子を用いた条件句を生成します。

 引数の指定方法は、「like()」メソッドと同様です。

  • both
  • $this->db->not_like('service_code', 'hoge');
    `service_code` NOT LIKE '%hoge%'
    $like = array(
        'service_code' => 'hoge',
        'shop_name' => 'foo',
    );
    $this->db->not_like($like);
    `service_code` NOT LIKE '%hoge%' AND `shop_name` NOT LIKE '%foo%'
  • before
  • $this->db->not_like('service_code', 'hoge', 'before');
    `service_code` NOT LIKE '%hoge'
    $like = array(
        'service_code' => 'hoge',
        'shop_name' => 'foo',
    );
    $this->db->not_like($like, , 'before');
    `service_code` NOT LIKE '%hoge' AND `shop_name` NOT LIKE '%foo'
  • after
  • $this->db->not_like('service_code', 'hoge', 'after');
    `service_code` NOT LIKE 'hoge%'
    $like = array(
        'service_code' => 'hoge',
        'shop_name' => 'foo',
    );
    $this->db->not_like($like, , 'after');
    `service_code` NOT LIKE 'hoge%' AND `shop_name` NOT LIKE 'foo%'

or_like($field, $match = '', $side = 'both')
or_not_like($field, $match = '', $side = 'both') 一番上に戻る

 「like()」メソッド、「not_like()」メソッドは、 複数の条件句を指定した場合、「AND」で連結していきますが、 「or_like()」「or_not_like()」メソッドは、「OR」で連結していきます。

 利用方法は、「like()」メソッド、「not_like()」メソッドと同様です。

    $this->db->or_like('service_code', 'hoge');
    $this->db->or_like('shop_name', 'foo');
    `service_code` LIKE '%hoge%' OR `shop_name` LIKE '%foo%'

    $like = array(
        'service_code' => 'hoge',
        'shop_name' => 'foo',
    );
    $this->db->or_like($like);
    `service_code` LIKE '%hoge%' OR `shop_name` LIKE '%foo%'

    $this->db->or_not_like('service_code', 'hoge');
    $this->db->or_not_like('shop_name', 'foo');
    `service_code` NOT LIKE '%hoge%' OR `shop_name` NOT LIKE '%foo%'

    $like = array(
        'service_code' => 'hoge',
        'shop_name' => 'foo',
    );
    $this->db->or_not_like($like);
    `service_code` NOT LIKE '%hoge%' OR `shop_name` NOT LIKE '%foo%'

論理演算子の優先順位

 論理演算子「AND」と「OR」では、「AND」の方が優先順位が高くなります。
 従って、ActiveRecordeでも、条件句を複数していく際には注意が必要です。

 例えば、「20才」以上の名前が「Tanaka」か「Suzuki」のデータを抽出するには、SQLの条件句は以下のようになります。

    `age` >= 20 AND ( `name` = 'Tanaka' OR `name` = 'Suzuki' )

 このSQLをActiveRecodeで実現しようと以下の様なコードを書くと誤りとなります。

    $this->db->where('age >=', 20);
    $this->db->where('name', 'Tanaka');
    $this->db->or_where('name', 'Suzuki');

    このコードが実行されるとデータベースオブジェクトに、下記のSQLクエリがキャッシュされてしまいます。

    `age` >= 20 AND `name` = 'Tanaka' OR `name` = 'Suzuki'

 これでは、「20才」以上の「Tanaka」と、全年齢の「Suzuki」のデータが抽出されてしまいます。

 CodeIgniterのActiveRecordで「優先順位を意図したものにする「()」を付加するには、「where()」メソッドに 具体的なSQLの一部を文字列を指定するしかありません。

 また、変数を文字列に当て込む場合は、事前にエスケープ処理を行っておく必要があります。

    $tanaka = $this->db->escape('Tanaka');
    $suzuki = $this->db->escape('Suzuki');

    $this->db->where('age >=', 20);
    $this->db->where("( `name` = {$tanaka} OR `name` = {$suzuki} )");

 これで、意図したSQLを発行することができます。

    `age` >= 20 AND ( `name` = 'Tanaka' OR `name` = 'Suzuki' )