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

发布于 2024-11-09 11:47:22 字数 333 浏览 0 评论 0原文

我正在获取产品列表。每个产品可能有一张或多张图片,我只想返回第一张图片。

$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 条记录?

I'm getting a product listing. Each product may have 1 or more image, I only want to return the first image.

$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');

Is there anyway to limit the db->join to 1 record using the CI active record class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

掐死时间 2024-11-16 11:47:22

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

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

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

Add $this->db->limit(1); before calling $this->db->get('products p');. See the docs at ellislab.com: search the page for limit.

EDIT: I misread the fact that you were trying to apply the LIMIT to the internal JOIN statement.

No. Since you can not do a LIMIT on an internal JOIN statement in regular SQL you can not do it with Code Igniter's ActiveRecord class.

软糯酥胸 2024-11-16 11:47:22

您可以使用 $this->db->group_byleft 连接来实现您想要的结果:

$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 为您提供结果code> (不重复产品),将 products_images 中的第一个匹配记录连接到每个结果行。如果连接表中没有匹配行(即缺少图像),您将获得 products_images 字段的空值,但仍会看到 products 表中的结果。

You can achieve what you want using $this->db->group_by with a left join:

$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();

This should give you results by products.id (without repetition of products), with the first matching record from products_images joined to each result row. If there's no matching row from the joined table (i.e. if an image is missing) you'll get null values for the products_images fields but will still see a result from the products table.

束缚m 2024-11-16 11:47:22

扩展@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

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

To expand on @Femi's answer:

There's no good way to limit the JOIN, and, in fact, you don't really want to. Assuming both products_image.product_id and products.id have indexes (and they absolutely should if you're going to join against them repeatedly) when the database engine does a join, it uses the indexes to determine what rows it needs to fetch. Then the engine uses the results to determine where on the disk to find the records it needs. If you

You should be able to see the difference by running these SQL statements:

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

as opposed to:

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

The first query should have an index, the second one will not. There should be a performance difference if there's a significant number of rows the the DB.

[浮城] 2024-11-16 11:47:22

也有这个问题,我解决它的方法是迭代结果并删除当前对象(如果 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 就是我们想要的

Had this issue too the way I solved it was iterating over the results and removing the current object if the product_id had existed in a previous one. Create a array, push the product_id's to it while checking if they are repeats.

$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

Now $result is what we want

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文