sql >> Database >  >> RDS >> Mysql

Welsprekend waarin met meerdere tabellen samenkomen

Houd er rekening mee dat de manier waarop u het probeert te doen, mogelijk meerdere rijen per item krijgt (eenmaal per gerelateerde vermelding). Een betere manier zou zijn om een ​​reeks aanbiedingen per item te hebben.

Als u welsprekende modellen gebruikt en de relaties correct heeft ingesteld, kunt u het volgende proberen:

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

Nu moet elk item een ​​listings hebben eigendom. Voor het eerste item kunt u bijvoorbeeld op de volgende manier toegang krijgen tot de aanbiedingen:

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

Merk op dat whereHas() zal waarschijnlijk een gecorreleerde EXISTS . maken subquery voor elk item in de $cats reeks. Als dat te traag is, kun je een JOIN-query gebruiken zoals:

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

Als je eloquent niet gebruikt, kun je het "gretige laden" ook zelf doen.

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



  1. Gegevens ophalen uit sql-database en weergeven in tabellen - Bepaalde gegevens weergeven volgens aangevinkte selectievakjes

  2. Wat is het verschil tussen SQL en MySQL?

  3. MySQL-rij 30153 is afgebroken door een GROUP_CONCAT()-fout

  4. Hoe selecteer ik datums van de laatste 30 dagen in MySQL, zelfs als de datums niet aanwezig zijn in mysql?