我有两个表:
产品
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"
));
这给了我想要的结果。但是,除了此以外,我还有很多过滤器,排序,关系和分页,这就是我尝试重写它的原因。
每个建议都值得赞赏。
答案 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();