Observe que do jeito que você está tentando fazer isso, você pode obter várias linhas por item (uma vez por listagem relacionada). Uma maneira melhor seria ter uma matriz de listagens por item.
Se você usa modelos eloquentes e configurou as relações corretamente, você pode tentar o seguinte:
$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();
Agora cada item deve ter uma
listings
propriedade. Por exemplo, para o primeiro item, você pode acessar as listagens da seguinte maneira:$item1 = $items[0];
$listings1 = $item1->listings;
Observe que
whereHas()
provavelmente criará um EXISTS
correlacionado subconsulta para cada entrada no $cats
variedade. Se isso for lento, você pode usar uma 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();
Se você não usa eloquente, você também pode fazer o "carregamento ansioso".
$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');
}