使用CodeIgniter活动记录类时限制SQL连接

时间:2011-05-24 03:39:48

标签: php mysql codeigniter

我正在收到产品清单。每个产品可能有1个或多个图像,我只想返回第一个图像。

$this->db->select('p.product_id, p.product_name i.img_name, i.img_ext');    
$this->db->join('products_images i', 'i.product_id = p.product_id', 'left');
$query = $this->db->get('products p');

是否有使用CI活动记录类将db-> join限制为1条记录?

4 个答案:

答案 0 :(得分:1)

在致电$this->db->limit(1);之前添加$this->db->get('products p');。请参阅ellislab.com上的文档:在页面中搜索限制

编辑:我误读了你试图将LIMIT应用于内部JOIN语句的事实。

没有。由于您无法在常规SQL中对内部JOIN语句执行LIMIT,因此无法使用Code Igniter的ActiveRecord类执行此操作。

答案 1 :(得分:0)

您可以使用$this->db->group_by加入left来实现您想要的效果:

$this->db->select('products.id, products.product_name, products_images.img_name, products_images.img_ext');
$this->db->from('products');
$this->db->join('products_images', 'products_images.product_id = products.id', 'left');
$this->db->group_by('products.id'); 
$query = $this->db->get();

这应该通过products.id(不重复产品)为您提供结果,其中products_images的第一个匹配记录加入到每个结果行。如果连接表中没有匹配的行(即,如果图像丢失),您将获得products_images字段的空值,但仍会看到products表的结果。

答案 2 :(得分:0)

扩展@Femi的回答:

没有好办法限制JOIN,事实上,你真的不想这样做。假设当数据库引擎进行连接时,products_image.product_idproducts.id都有索引(如果你要反复加入它们,它们绝对应该加入),它会使用索引来确定它需要哪些行取。然后引擎使用结果来确定磁盘上的位置以查找所需的记录。如果你

您应该能够通过运行这些SQL语句来查看差异:

EXPLAIN 
SELECT p.product_id, p.product_name, i.img_name, i.img_ext
FROM products p
LEFT JOIN products_images i
    ON i.product_id = p.product_id

而不是:

EXPLAIN  
SELECT p.product_id, p.product_name, i.img_name, i.img_ext
FROM (SELECT product_id, product_name FROM products) p 
LEFT JOIN (SELECT img_name, img_ext FROM products_images) i
    ON i.product_id = p.product_id

第一个查询应该有一个索引,第二个查询不会。如果DB存在大量行,则应该存在性能差异。

答案 3 :(得分:0)

如果我解决了这个问题,那么迭代结果并删除当前对象(如果product_id存在于前一个中)。创建一个数组,将product_id推送到它,同时检查它们是否重复。

$product_array = array();
$i = 0;

foreach($result as $r){

    if(in_array($r->product_id,$product_array)){
        unset($result[$i]);
    }else{
        array_push($product_array,$r->product_id);
    }
    $i++;

} 

$result = array_values($result); //re-index result array

现在$ result是我们想要的