Showing posts with label kohana. Show all posts
Showing posts with label kohana. Show all posts

Tuesday, February 21, 2012

Kohana nested SELECT statment

Problem
You need to join two tables using a nested SELECT statement.  However, Kohana's Database module doesn't really allow this query:
mysql> select forum_categories.*, (
    ->     select count(forum_data.id)
    ->     from forum_data
    ->     where forum_data.category_id = forum_categories.id and
    ->     forum_data.parent_id = '0'
    -> ) as cat_count
    -> from forum_categories;
+----+----------------+------------------------+-----------+
| id | title          | description            | cat_count |
+----+----------------+------------------------+-----------+
|  1 | Category One   | category 1 description |         2 |
|  2 | Category Two   | category 2 description |         2 |
|  3 | Category Three | category 3 description |         0 |
|  4 | Category Four  | category 4 description |         0 |
|  5 | Category Five  | category 5 description |         1 |
|  6 | Category Six   | category 6 description |         0 |
+----+----------------+------------------------+-----------+
6 rows in set (0.01 sec)

Solution
Rewrite your query as a left outer join (or inner join, depending on your case):
mysql>  select forum_categories.*, ifnull(forum_data.total, 0) as total
    ->   from forum_categories
    ->   left join (
    ->       select category_id, count(forum_data.id) as total
    ->       from forum_data where parent_id = '0'
    ->       group by category_id
    ->   ) as forum_data
    ->   on forum_data.category_id = forum_categories.id;
+----+----------------+------------------------+-------+
| id | title          | description            | total |
+----+----------------+------------------------+-------+
|  1 | Category One   | category 1 description |     2 |
|  2 | Category Two   | category 2 description |     2 |
|  3 | Category Three | category 3 description |     0 |
|  4 | Category Four  | category 4 description |     0 |
|  5 | Category Five  | category 5 description |     1 |
|  6 | Category Six   | category 6 description |     0 |
+----+----------------+------------------------+-------+
6 rows in set (0.01 sec)

Translating to Kohana, we now have:

$subquery = DB::select('category_id', array('COUNT("forum_data.id")', 'total'))
 ->from('forum_data')
 ->where('parent_id', '=', '0')
 ->group_by('category_id');

$query = DB::select('forum_categories.*', array('IFNULL("forum_data.total", 0)', 'total'))
 ->from('forum_categories')
 ->join(array($subquery, 'forum_data'), 'LEFT')
 ->on('forum_data.category_id', '=', 'forum_categories.id')
 ->as_object()
 ->execute();

For more info, check out the Subqueries section of Kohana's Query Builder documentation.