我想在 Laravel 中实现这个:
SELECT * FROM products JOIN
(SELECT product_id, MIN(price) AS lowest FROM prices GROUP BY product_id) AS q1
ON products.id = q1.product_id
ORDER BY q1.lowest;
我写了这个,但显然有问题:
$products = new Product();
$products = $products->join(
Price::whereNotNull('price')->select('product_id', DB::raw('min(price) as lowest'))->groupBy('product_id'), 'products.id', '=', 'product_id'
)->orderBy('lowest')->get();
我得到的错误:
ErrorException in Grammar.php line 39:
Object of class Illuminate\Database\Eloquent\Builder could not be converted to string.
我目前正在使用 join(DB::raw('(SELECT product_id, MIN(price) AS lowest FROM prices WHERE price IS NOT NULL GROUP BY product_id) AS q1'), 'products.id' , '=', 'q1.product_id')
作为解决方法。只是想知道如何以 Eloquent 方式做到这一点?谢谢。
最佳答案
在这种情况下,如果您出于效率原因想要进行单个查询,Eloquent 不会对您有太大帮助,这是可能的,但很麻烦。对于这种情况,您有 QueryBuilder。
DB::table('products')
->join(
DB::raw('(SELECT product_id, MIN(price) AS lowest FROM prices GROUP BY product_id) AS q1'),
'products.id', '=', 'q1.product_id'
)
->orderBy('q1.lowest')->get();
如果您将 get()
更改为 getSql()
,您将得到以下内容
select * from `products` inner join
(SELECT product_id, MIN(price) AS lowest FROM prices GROUP BY product_id) AS q1
on `products`.`id` = `q1`.`product_id` order by `q1`.`lowest` asc
不幸的是,据我所知您不能在没有 DB::raw 的情况下使用子查询,但是只要您不在查询中输入用户输入,它就不是不安全的。即使在那种情况下,您也可以通过使用 PDO 安全地使用它。
至于 Eloquent,你的产品模型甚至没有 price
字段(它可能有一个返回关系对象的 prices()
函数)所以它没有获得具有与其关联的单一价格的 Product
模型是有意义的。
编辑:
您也可以eager load关系,即(假设您将模型关系设置为 Trong Lam Phan 的示例)
$products = Product::with('prices')->get();
foreach ($products as $product)
{
$minPrice = $product->prices->min('price');
// Do something with $product and $minPrice
}
这只会运行一个查询,但是 min()
操作不是由数据库完成的。
关于php - Laravel Eloquent 如何加入查询而不是表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37770105/