Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Eloquent, wobei mehrere Tische beitreten

Beachten Sie, dass Sie so, wie Sie es versuchen, möglicherweise mehrere Zeilen pro Artikel erhalten (einmal pro zugehöriger Auflistung). Ein besserer Weg wäre, ein Array von Einträgen pro Artikel zu haben.

Wenn Sie eloquente Modelle verwenden und die Beziehungen korrekt eingerichtet haben, können Sie Folgendes versuchen:

$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();

Jetzt sollte jeder Artikel einen listings haben Eigentum. Zum Beispiel können Sie für den ersten Artikel wie folgt auf die Listen zugreifen:

$item1 = $items[0];
$listings1 = $item1->listings;

Beachten Sie, dass whereHas() wird wahrscheinlich ein korreliertes EXISTS erzeugen Unterabfrage für jeden Eintrag in $cats Reihe. Wenn das zu langsam ist, können Sie eine JOIN-Abfrage verwenden wie:

$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();

Wenn Sie nicht eloquent sind, können Sie das "Eifrigladen" auch selbst erledigen.

$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');
}