我正在收到产品清单。每个产品可能有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条记录?
答案 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_id
和products.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是我们想要的