Tenga en cuenta que, de la forma en que intenta hacerlo, es posible que obtenga varias filas por elemento (una vez por lista relacionada). Una mejor manera sería tener una variedad de listados por artículo.
Si usa modelos elocuentes y ha configurado las relaciones correctamente, puede intentar lo siguiente:
$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();
Ahora cada artículo debe tener un listings
propiedad. Por ejemplo, para el primer artículo, puede acceder a los listados de la siguiente manera:
$item1 = $items[0];
$listings1 = $item1->listings;
Tenga en cuenta que whereHas()
probablemente creará un EXISTS
correlacionado subconsulta para cada entrada en $cats
formación. Si eso es demasiado lento, puede usar una consulta JOIN como:
$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();
Si no usa elocuente, también puede hacer la "carga ansiosa" usted mismo.
$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');
}