我正在尝试获取以下查询的结果:返回所选日期可用的用户。用户选择何时不可用,并将其存储在具有开始日期时间和结束日期时间的“可用性”表中。 以下是我一直在尝试但没有成功...我继续让错误的用户回来,如果他们设置了多个不可用时间段,它也将返回它们。
尝试#1
User::whereHas('availabilities', function($q)use($selected_date_time)
{
$q->where('unavailable_start_date', '>', $selected_date_time)
->where('unavailable_end_date', '>', $selected_date_time);
})->orWhereHas('availabilities', function($q)use($selected_date_time)
{
$q->where('unavailable_start_date', '<', $selected_date_time)
->where('unavailable_end_date', '<', $selected_date_time);
})->with('availabilities')->get();
尝试#2
User::whereHas('availabilities', function($q)use($selected_date_time)->whereHas('availabilities', function($q)use($selected_date_time)
{
$q->whereRaw('? NOT BETWEEN `unavailable_start_date` AND `unavailable_end_date`', [$selected_date_time]);
})->get();
这是在try#1案例中执行的mysql查询:
select * from `users` where `is_user` = ? and (select count(*) from `availabilities` where `availabilities`.`user_id` = `users`.`id` and `unavailable_start_date` > ? and `unavailable_end_date` > ?) >= 1 or (select count(*) from `availabilities` where `availabilities`.`user_id` = `users`.`id` and `unavailable_start_date` < ? and `unavailable_end_date` < ?) >= 1
日期过时了:
selected string(19) "2014-11-13 11:00:00"
unavailableStart string(19) "2014-11-12 11:30:00"
unavailableEnd string(19) "2014-11-18 11:00:00"
Ant知道出了什么问题或如何解决这个问题?
编辑完整查询
$photographers_available = Photographer::where('is_photographer', '=', '1')
->whereHas('studioAddress', function($q)use($city_id)
{
$q->where('city_id', '=', $city_id);
})
->orWhereHas('user', function($q)use($city_id) // TK could reduce to 'user.address' I think
{
$q->whereHas('address', function($q)use($city_id)
{
$q->where('city_id', '=', $city_id);
});
})
->whereHas('stypesPhotographer', function($q)use($stype)
{
$q->where('shooting_type_id', '=', $stype);
})
->where(function ($q) use ($selected_date_time) {
$q->whereHas('availabilities', function($q)use($selected_date_time)
{
$q->where('unavailable_start_date', '>', $selected_date_time)
->where('unavailable_end_date', '>', $selected_date_time);
})->orWhereHas('availabilities', function($q)use($selected_date_time)
{
$q->where('unavailable_start_date', '<', $selected_date_time)
->where('unavailable_end_date', '<', $selected_date_time);
});
})
->with('availabilities')
->get();
在思考之后,orWhereHas是否会让它出错?
谢谢!
答案 0 :(得分:2)
User::whereHas('availabilities', function ($q) use ($dt) {
$q->where('unavailable_start_date', '<=', $dt)
->where('unavailable_end_date', '>', $dt);
}, '=', 0)->get();
所以我们在某种程度上扭转了这一点。我们在where里面设置查询以查找此范围内的可用性,不可用性。所以我们正在查询所有不可用的记录(在某种程度上)。然后我们通过使用whereHas('=', 0
)的其他参数来抓取那些没有符合此条件的关系的用户。
因此,无论有多少可用性记录,都不会返回具有此关系的任何属于此时间范围的用户。如果他们中的任何一个符合条件,他们就不会通过过滤器。
答案 1 :(得分:1)
编辑 tldr;请记住对where
mehtods使用嵌套orWhatever
。除此之外,@ lagbox为您提供了原始发布问题的正确答案。这是完整的解决方案:
$photographers_available = Photographer::where('is_photographer', '=', '1')
->where(function ($q) use($city_id){
$q->whereHas('studioAddress', function($q)use($city_id) {
$q->where('city_id', '=', $city_id);
})
->orWhereHas('user', function($q)use($city_id) {
$q->whereHas('address', function($q)use($city_id) {
$q->where('city_id', '=', $city_id);
});
});
})
->whereHas('stypesPhotographer', function($q)use($stype) {
$q->where('shooting_type_id', '=', $stype);
})
->where(function ($q) use ($selected_date_time) {
$q->whereHas('availabilities', function($q)use($selected_date_time) {
$q->where('unavailable_start_date', '>', $selected_date_time)
->where('unavailable_end_date', '>', $selected_date_time);
})->orWhereHas('availabilities', function($q)use($selected_date_time) {
$q->where('unavailable_start_date', '<', $selected_date_time)
->where('unavailable_end_date', '<', $selected_date_time);
});
})
->with('availabilities')
->get();
假设您的where
条款适合您的情况,这就是您所需要的:
User::where(function ($q) use ($selected_date_time) {
$q->whereHas('availabilities', function($q)use($selected_date_time)
{
$q->where('unavailable_start_date', '>', $selected_date_time)
->where('unavailable_end_date', '>', $selected_date_time);
})->orWhereHas('availabilities', function($q)use($selected_date_time)
{
$q->where('unavailable_start_date', '<', $selected_date_time)
->where('unavailable_end_date', '<', $selected_date_time);
});
})->with('availabilities')->get();
因为,正如我们在这里看到的那样:
select * from `users`
where `is_user` = ?
and (...) >= 1
// culprit:
or (...) >= 1
由于(可能)是全局范围,您需要嵌套orWhere
。
答案 2 :(得分:0)
试试这个对我有用 ...
如果使用Eloquent ORM:
User::Where(function($query) use ($selected_date_time)
{
$query->where('unavailable_start_date','>',$selected_date_time);
$query->where('unavailable_end_date','>',$selected_date_time);
})
->orWhere(function($query)
{
$query->where('unavailable_start_date','<',$selected_date_time);
$query->where('unavailable_end_date','<',$selected_date_time);
})
以上就是这样的(在我的表格中导致以下查询)
select * from `equipments` where (`created_at` > '2014-10-29' and `updated_at` > '2014-10-29') or (`created_at` < '2014-10-29' and `updated_at` < '2014-10-29')
评论如果不起作用......