Getting just the latest value on a joined table with Eloquent

后端 未结 2 1493
自闭症患者
自闭症患者 2020-11-29 07:31

I have two tables like this:

products:

+----+-----------+
| id |   name    |
+----+-----------+
|  1 | Product 1 |
|  2 | Product 2          


        
2条回答
  •  广开言路
    2020-11-29 08:26

    When Laravel eager loads a relationship, it will perform two queries similar to this:

    SELECT * FROM products WHERE 1;
    SELECT * FROM prices WHERE product_id = 1;
    

    What you want to do is to add a condition to the second query to get the row with most recent price. So you would want something like this:

    SELECT * FROM products WHERE 1;
    SELECT * FROM prices WHERE product_id = 1 ORDER BY price;
    

    Luckily in Laravel's Eager Load Constraints you can, instead of passing a string into with(), you can pass an array with the relationship name as key and a subquery closure as its value. Like this:

    $products = Product::with(array('prices' => function($query)
    {
        $query->orderBy('created_at', 'desc');
    }))->get();
    

    Then in your code you can do:

    $product->prices->first();
    

    to get the most recent price of each product.

    Note: You may notice that Laravel will still load all the prices for each product. I don't think there's a way around it while still using purely Eloquent because the way eager loading work is fetching all the relationship records in one single query, so there isn't an easy way to say get only the most recent price for each product.


    Another solution:

    However, if you are strictly needing to know just a value from another table, you could do a sub-select instead:

    $products = Product::select('*')
        ->addSelect(DB::raw('(SELECT price FROM prices WHERE products.id = prices.product_id ORDER BY created_at DESC LIMIT 1) price'))
        ->get();
    

提交回复
热议问题