[英]Limit SQL join when using CodeIgniter active record class
我正在获取产品列表。 每个产品可能有一张或多张图片,我只想返回第一张图片。
$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活动记录class将db->join限制为1条记录?
添加$this->db->limit(1);
在调用$this->db->get('products p');
. 请参阅ellislab.com上的文档:在页面中搜索limit 。
编辑:我误读了您试图将 LIMIT 应用于内部 JOIN 语句的事实。
不,由于您不能在常规 SQL 中对内部 JOIN 语句执行 LIMIT,因此您不能使用 Code Igniter 的 ActiveRecord ZA2F2ED4F8EBC2CBB4C21A29DC40AB61Z 来执行此操作。
您可以使用带有left
连接的$this->db->group_by
来实现您想要的:
$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 字段的 null 值,但仍会从products
表中看到结果。
扩展@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
第一个查询应该有一个索引,第二个没有。 如果数据库中有大量行,则应该存在性能差异。
如果 product_id 存在于前一个中,那么我解决的方法也是迭代结果并删除当前的 object。 创建一个数组,将 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 就是我们想要的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.