我有 2 个这样结构的表
产品
- ID
- 标题
计划
- ID
- 产品 ID
- 价格
- 类型
基本上,这个想法是为每个产品设置多个价格,每个产品的最后一个计划将是其当前价格,如果其被删除或过期,它将回退到之前的计划
因此,如果产品有 2 个 ID 为 (1, 2)
的计划,则 id = 2
的计划将是其当前价格
我想展示他们最近计划的产品type = off
这是由 Laravel ORM Eloquent
生成的 SQL 查询
select * from `products` where exists
(select * from `plans` where `products`.`id` = `plans`.`product_id`
and `type` = 'off'
and `plans`.`deleted_at` is null)
and `products`.`deleted_at` is null
问题是它不会检查最后/当前计划,它会在所有计划中搜索...所以即使 id = 2
类型的计划未关闭并且如果 plan.id = 1
类型已关闭 我仍然会在查询中包含此产品
这是 PHP 代码:
$wonder_product = Product::whereHas('CurrentPlan', function ($q) {
$q->where('type', 'off');
})->get();
最佳答案
尝试使用 GROUP BY 子查询:
$wonder_product = Product::whereHas('CurrentPlan', function ($q) {
$q->where('type', 'off')
->whereIn('id', function ($subquery) {
$subquery
->from(with(new CurrentPlan)->getTable())
->select(DB:raw('MAX(id)'))
->groupBy('product_id');
});
})->get();
或者,如果您可以接受原始子查询:
$wonder_product = Product::whereHas('CurrentPlan', function ($q) {
$q->where('type', 'off')
->whereRaw('id in (select max(id) from plans group by product_id)')
})->get();
如果我没记错的话,这两种方法都应该生成如下查询:
select * from `products`
where exists (
select * from `plans`
where `products`.`id` = `plans`.`product_id`
and `type` = 'off'
and `plans`.`deleted_at` is null
and id in (select max(id) from plans group by product_id)
)
and `products`.`deleted_at` is null
但如果是我,我可能会编写这样的原始查询:
$wonder_product = Product::hydrateRaw('
select products.*
from products
where 'off' = (
select plans.type
from plans
where plans.product_id = products.id
and plans.deleted_at is null
order by plans.id desc
limit 1
)
and products.deleted_at is null
');
关于php - MySQL查询: get the last row of related table on multi table selection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57774947/