phpdatabasecodeigniteractiverecordsubquery

Convert SQL with subquery as part of JOIN's ON condition to CodeIgniter active record syntax


How do I write the following query as a CodeIgniter active record script?

select
    tbl_list.id,
    tbl_list_items.name
from
    tbl_list
join
    tbl_list_items
    on tbl_list_items.id=(
        select
            tbl_list_items.id
        from
            tbl_list_items
        where
            list_id=tbl_list.id
        order by
            tbl_list_items.item_no asc
        LIMIT 1
    )

I came up with this, but it does not do the job.

$this->db->select($this->table_list.'.*');
$this->db->from($this->table_list);

$sub = $this->subquery->start_subquery('join','',$this->table_list_items.'.id');
$sub->select('id')->from($this->table_list_items)->where('list_id','tbl_list.id')->order_by($this->table_list_items.'item_no','asc')->limit('1');
$this->subquery->end_subquery('list_items');

Solution

  • Review the Active Record methods available to you in CodeIgniter.

    Then review a CI library to extend it to handle subqueries available on CodeIgniter.

    A walk-through about how CI is doing this under-the-hood.

    A GitHub codebase for implementing subqueries in CodeIgniter 1.7 and 2.x.

    The code would be similar to (untested):

    $this->db->select('tbl_list.id, tbl_list.names');
    $this->db->from('tbl_list');
    $sub = $this->subquery->start_subquery('join', 'left', 'tli.id = tbl_list.id');
    $sub->select('tbl_list_items.id')->from('tbl_list_items')->where('tbl_list_items.list_id=tbl_list.id ');
    $sub->db->order_by('ASC');
    $sub->db->limit(1);
    $this->subquery->end_subquery('tli');
    

    The key is $this->subquery->end_subquery('tli');. It names the result of the subquery via AS tli so that you can reference it in tli.id.