我有4个表,项目,列表,catitem_item和item_listing。
项目和列表是多对多的关系。 物品和催产物也是很多很多的关系。catitems包含项目类别列表。 列表就像物品所在的位置。 示例列表商店A可以具有项目主席和项目主席具有多个catitem类别。
我的目标是获取类别列表中的项目,例如类别1和2和3($cats
)以及此项目所在的列表信息。
因此,如果有6个主席列表,它将返回6个主席结果。
这是我到目前为止的查询。
$items = DB::table('items')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->join('item_listing', 'item_listing.item_id', '=', 'items.id')
->join('listings', 'item_listing.listing_id', '=', 'listings.id')
->whereIn('catitem_item.catitem_id', $cats)
//->groupBy('items.id')
//->having(DB::raw('count(*)'), '=', count($cats))
->select('items.id', 'items.name', 'items.price', 'items.slug', 'item_listing.listing_id', 'listings.name as listing_name', 'listings.slug as listing_slug')
->get();
答案 0 :(得分:0)
请注意,尝试这样做的方式,每个项目可能会有多行(每个相关列表一次)。更好的方法是每个项目都有一系列列表。
如果您使用雄辩模型并且已正确设置关系,则可以尝试以下操作:
$cats = [1, 2, 3];
$query = Item::with('listings');
foreach ($cats as $cat) {
$query->whereHas('catitems', function($q) use($cat) {
$q->where('id', $cat);
});
}
$items = $query->get();
现在每个项目都有一个listings
属性。例如,对于第一个项目,您可以通过以下方式访问列表:
$item1 = $items[0];
$listings1 = $item1->listings;
请注意,whereHas()
可能会为EXISTS
数组中的每个条目创建一个相关的$cats
子查询。如果这样做很慢,您可以使用JOIN查询,如:
$items = Item::with('listings')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->whereIn('catitem_item.catitem_id', $cats)
->groupBy('items.id')
->having(DB::raw('count(*)'), '=', count($cats))
->select('items.*')
->get();
如果你不使用雄辩的话,你也可以进行"渴望加载"自己。
$items = DB::table('items')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->whereIn('catitem_item.catitem_id', $cats)
->groupBy('items.id')
->having(DB::raw('count(*)'), '=', count($cats))
->select('items.*')
->get()
->keyBy('id');
foreach ($items as $item) {
$item->listings = [];
}
$itemIds = $items->pluck('id');
$listings = DB::table('listings')
->join('item_listing', 'item_listing.listing_id', '=', 'listings.id')
->whereIn('item_listing.item_id', $itemIds)
->groupBy('listings.id')
->select('listings.*', DB::raw('group_concat(item_listing.item_id) as item_ids'))
->get();
foreach ($listings as $listing) {
$itemIds = explode(',', $listing->item_ids);
foreach ($itemIds as $itemId) {
$items[$itemId]->listings[] = $listing;
}
$listing->forget('item_ids');
}