Reputation: 553
I have this query to convert into the Active record
SELECT (
SELECT image
FROM bc_item_image
WHERE item_id = i.id
LIMIT 1
) as item_image,
i.description,
i.condition,
c.cat_name as category_name,
i.id as ID
FROM bc_item i,bc_category c
WHERE i.cat_id = c.id
and i.user_id !='$user_id'
and i.status = '1'
and i.is_bartered = '0'
and i.is_cancel = '0'
and FIND_IN_SET('$subcat_id',i.interested_cat)
order by i.display_count desc
How can this be scripted using query builder methods in CodeIgniter?
Upvotes: 1
Views: 76
Reputation: 47864
First, the subquery in your SELECT clause is not advisable for performance reasons; instead JOIN or LEFT JOIN the subquery to relate the required data.
Second, implicit / old skool comma-JOINs are commonly frowned upon because they can be overlooked by human developers. The SQL intention is more obvious when JOIN and ON/USING syntax is used.
Third, I won't change it, but FIND_IN_SET() generally indicates that you should restructure your database to avoid delimited values in a single column.
$subquery = $this->db
->select('item_id, MIN(image) image')
->group_by('item_id')
->get_compiled_select('bc_item_image');
return $this->db
->select([
'img.image item_image',
'i.description',
'i.condition',
'c.cat_name category_name',
'i.id id'
])
->join('bc_category c', 'i.cat_id = c.id')
->join("($subquery) img", 'i.id = img.item_id', 'LEFT')
->where([
'i.user_id !=' => $user_id,
'i.status' => 1,
'i.is_bartered' => 0,
'i.is_cancel' => 0,
"FIND_IN_SET($subcat_id, i.interested_cat)" => null
])
->order_by('i.display_count', 'DESC')
->get('bc_item i')
->result();
The value used in the first parameter of FIND_IN_SET()
will not be quoted. If this is needed, then wrap that variable in escape()
like $this->db->escape($subcat_id)
If $user_id = 4;
and $subcat_id = 11;
, then the rendered SQL* will resemble the following.
SELECT `img`.`image` `item_image`,
`i`.`description`,
`i`.`condition`,
`c`.`cat_name`
`category_name`,
`i`.`id` `id`
FROM `bc_item` `i`
JOIN `bc_category` `c` ON `i`.`cat_id` = `c`.`id`
LEFT JOIN (
SELECT `item_id`, MIN(image) image
FROM `bc_item_image`
GROUP BY `item_id`
) img ON `i`.`id` = `img`.`item_id`
WHERE `i`.`user_id` != 4
AND `i`.`status` = '1'
AND `i`.`is_bartered` = '0'
AND `i`.`is_cancel` = '0'
AND FIND_IN_SET(11, i.interested_cat)
ORDER BY `i`.`display_count` DESC
* I added my own custom spacing for readability and the identifier/string quoting may vary based on db dialect/driver.
Upvotes: 0
Reputation: 1963
$this->db->select(" i.description, i.condition,c.cat_name as category_name,i.id,(SELECT image FROM bc_item_image WHERE item_id = i.id LIMIT 1) as item_image");
$this->db->from('bc_item as i');
$this->db->join('bc_category as c', 'i.cat_id = c.id');
$this->db->where('i.status', 1);
$this->db->where('i.is_bartered', 0);
$this->db->where('i.user_id','!=', $user_id);
$this->db->where('i.is_cancel', 0);
$this->db->where("FIND_IN_SET('".$subcat_id."','i.interested_cat')");
$query = $this->db->get();
Upvotes: 0