有没有办法使用Laravel查询生成器重写此原始SQL查询

时间:2019-12-12 13:16:02

标签: laravel

我有两个表:

产品

id | code | supplier_id |...

company_product

id | retail_price | copmany_id |...

我有多个在线商店,这些商店通过我在本地存储的API提取产品。它几乎可以用来比较它们的价格,单位库存等,这可以通过在所有商店中都相同的产品代码来完成。

我只提取一次所有产品,每天更新两次。使用该平台的其他公司(假设为“平台”)根据其合同的产品价格有所不同,这些价格均保存在第二张表中。

我要实现的目的是列出所有产品,但仅列出该产品代码中最便宜的产品版本。

我可以通过以下查询来实现。

$products = DB::select(DB::raw(
    "select p.*, t.price_min
     from (select MAX(p.id) as id, p.code, MIN(cp.retail_price) as price_min
     from products as p
     left join company_product as cp on cp.product_id = p.id
     group by p.code) as t
     left join products as p on p.id = t.id"
));

这给了我想要的结果。但是,除了此以外,我还有很多过滤器,排序,关系和分页,这就是我尝试重写它的原因。

每个建议都值得赞赏。

1 个答案:

答案 0 :(得分:1)

首先,您可能希望在此处使用的原始MySQL查询只是一个内部联接:

SELECT p.*, t.price_min
FROM products p
INNER JOIN
(
    SELECT p.code, MAX(p.id) AS max_id, MIN(cp.retail_price) AS price_min
    FROM products p
    INNER JOIN company_product cp ON cp.product_id = p.id
    GROUP BY p.code
) t
    ON p.id = t.max_id

对于Laravel代码,我们可以尝试在单独的变量中创建子查询,然后将其联接:

$subquery = DB::table('products AS p')
    ->select([
        'p.code',
         DB::raw('MAX(p.id) AS max_id, MIN(cp.retail_price) AS price_min')])
    ->join('company_product AS cp', 'cp.product_id', '=', 'p.id')
    ->groupBy('p.code');

$query = DB::table('products AS p')
    ->select('p.*', 't.price_min')
    ->innerJoinSub($subquery, 't', function($join) {
        $join->on('p.id', '=', 't.max_id');
    })
    ->get();
相关问题