【发布时间】:2017-03-02 07:50:56
【问题描述】:
我不明白为什么这不起作用:
Device::with(['travel.move.position' => function($q) use ($start, $end) {
return $q->whereBetween('created_date', [$start, $end]);
}]);
我认为它应该给我所有具有travel->move->position 关系的设备,但只有那些position.datetime 介于$start 和$end 之间的设备
我尝试了类似的东西
Device::whereHas('travel.move.position', function($q) use ($start, $end) {
return $q->whereBetween('created_date', [$start, $end]);
});
我得到了预期的结果,但我没有得到渴望的关系。
为答案 1 添加了查询:
select *
from `devices`
where exists (
select * from `travels`
inner join `travel_info` on `travel_info`.`id` = `travels`.`info_id`
where `devices`.`id` = `travel_info`.`device_id`
and exists (
select *
from `moves`
where `moves`.`travel_id` = `travels`.`id`
and exists (
select * from `positions`
where `moves`.`position_id` = `positions`.`id` and `created_at`
between ? and ?
)
)
查询是完美的(就像 whereHas 一样)但是何时使用 with():
select `travels`.*, `travel_info`.`device_id`
from `travels`
inner join `travel_info` on `travel_info`.`id` = `travels`.`info_id`
where `travel_info`.`device_id` in (?, ?, ?)
....
select * from `moves` where `moves`.`travel_id` in (?, ..., ?)
....
select * from `positions` where `positions`.`id` in (?, ..., ?)
【问题讨论】:
-
这段代码只过滤
position,而不是device。因此,您仍将获得所有设备,但在每个设备->旅行->移动关系中,您只会看到与您的过滤器匹配的位置。 -
你的领域真的叫
datetime吗?由于这是 mysql 中的保留字:dev.mysql.com/doc/refman/5.7/en/keywords.html 我想你可能需要引用它whereBetween('datetime', [$start, $end]); -
尝试将
with('travel.move.position')添加到您的第二个查询中。然后它会为您提供预期的结果以及急切加载的关系。 -
@Cyclone 。不,它是一个西班牙语单词,意思相同,但我为了更好地理解而改变了。
-
@kanashin - haha okej 然后我明白了 - 也许你应该把它改成其他的东西,比如
created_time等 =)
标签: laravel relationship