sql >> データベース >  >> RDS >> Mysql

複数のテーブルを結合することで雄弁

    あなたがそれをしようとしている方法では、アイテムごとに複数の行を取得する可能性があることに注意してください(関連するリストごとに1回)。より良い方法は、アイテムごとに一連のリストを作成することです。

    雄弁なモデルを使用していて、関係を正しく設定している場合は、次のことを試すことができます。

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



    1. 結果の列名を知らなくてもSQL Server Pivotできますか?

    2. mysqlでキリル文字をエンコードする方法は?

    3. MySQL-各「グループ」から2行のみを選択します

    4. Pythonを介してMySQLからバッチでデータを取得する