php - 使用嵌套关系的结果查询关系
问题描述
在这里,我有下面的代码,我想过滤我的酒店并为每家酒店选择最低价格的房间:
$city_id = $request->get('city_id');
$stars = $request->get('grade_stars');
$type_id = $request->get('accommodation_type_id');
$from_date = $request->get('from_date');
$to_date = $request->get('to_date');
$data = Accommodation::with(['city','accommodationRoomsLimited.roomPricingHistorySearch' =>function($query) use($from_date,$to_date){
$query->whereDate('from_date', '<=', $from_date);
$query->whereDate('to_date', '>=', $to_date);
}])
->whereIn('city_id',$city_id)
->whereIn('grade_stars',$stars)
->orWhere('accommodation_type_id',$type_id)
->paginate(10);
return $data;
这是我的住宿模式:
public function accommodationRoomsLimited()
{
return $this->Hasmany(AccommodationRoom::class)->select('id', 'accommodation_id');
}
在我的住宿房间模型中:
public function roomPricingHistorySearch()
{
return $this->hasOne(RoomPricingHistory::class,'accommodation_room_id','id')->orderBy('sales_price','ASC');
}
我有一个名为房间定价历史记录的表,它记录每天的房间价格这是我在 api 中的输出,我想在 room_pricing_history_search 中选择 1 个具有最低 sales_price 的房间:
"accommodation_rooms_limited": [
{
"id": 4859,
"accommodation_id": 47,
"room_pricing_history_search": {
"id": 15741,
"accommodation_room_id": 4859,
"net_price": null,
"sales_price": 50,
"created_at": "2019-05-25 13:30:00",
"updated_at": "2019-05-25 13:30:00"
}
},
{
"id": 4860,
"accommodation_id": 47,
"room_pricing_history_search": {
"id": 4990,
"accommodation_room_id": 4860,
"net_price": null,
"sales_price": 1760000,
"created_at": "2019-05-25 13:30:00",
"updated_at": "2019-05-25 13:30:00"
}
},
{
"id": 4861,
"accommodation_id": 47,
"room_pricing_history_search": {
"id": 4991,
"accommodation_room_id": 4861,
"net_price": null,
"sales_price": 2270000,
"created_at": "2019-05-25 13:30:00",
"updated_at": "2019-05-25 13:30:00"
}
},
{
"id": 4862,
"accommodation_id": 47,
"room_pricing_history_search": {
"id": 4992,
"accommodation_room_id": 4862,
"net_price": null,
"sales_price": 2780000,
"created_at": "2019-05-25 13:30:00",
"updated_at": "2019-05-25 13:30:00"
}
}
]
},
解决方案
从选择房间而不是酒店开始,然后按酒店分组可能更简单。
您可以使用原始表达式来获得最低房价:
$raw = DB::raw('min(price) as min_price');
然后从房间表中选择并按酒店 ID 分组:
Room::join('hotels', 'hotels.id' ,'=', 'rooms.hotel_id')
->whereDate('rooms.from_date', '<=', $from_date)
->whereDate('rooms.to_date', '>=', $to_date)
->select('hotels.*', $raw)
->groupBy('hotels.id')
->get()
Jonathan Reinink 最近的演讲 Eloquent Performance Patterns可能也会让您感兴趣。他谈到了与你类似的查询,看起来他谈到的拉取请求将使这些查询更容易已经合并到 Laravel 6.0 中。所以从 Laravel 6.0 你应该可以做这样的事情:
return Hotel::addSelect(['lowest_price' => function ($query) {
$query->select('price')
->from('rooms')
->whereColumn('hotel_id', 'hotels.id')
->orderBy('price', 'asc')
->limit(1);
}])->get();
推荐阅读
- javascript - 如何使用 VueJS 防止数字输入
- android - Android 无法构建:在根项目 'android' 中找不到任务 'assemble'
- active-directory - 唯一的 x500 对象 ID 创建
- javascript - 在与 React.DOM 和我的组件之一相关的 React 应用程序中不断出现渲染错误
- javascript - 用对象实例化变量会将对象变成函数,然后对象数据成员返回 undefined
- java - Java equals 方法无法按预期工作
- orientdb - OrientDB console diagnostic - not very helpful?
- vb.net - 从 datagridview Visual Basic 2010 绘制图表
- php - 高级 Laravel 合并数据/模型 - 可以在模型级别完成吗?
- ios - 如何在 iPhone 真机上打开数据库 sqlite 文件?