雄辩,其中加入多个表

时间:2017-08-09 17:40:32

标签: php mysql laravel eloquent laravel-eloquent

我有4个表,项目,列表,catitem_item和item_listing。

项目和列表是多对多的关系。 物品和催产物也是很多很多的关系。

catitems包含项目类别列表。 列表就像物品所在的位置。 示例列表商店A可以具有项目主席和项目主席具有多个catitem类别。

我的目标是获取类别列表中的项目,例如类别1和2和3($cats)以及此项目所在的列表信息。 因此,如果有6个主席列表,它将返回6个主席结果。

这是我到目前为止的查询。

$items = DB::table('items')
                ->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
                ->join('item_listing', 'item_listing.item_id', '=', 'items.id')
                ->join('listings', 'item_listing.listing_id', '=', 'listings.id')
                ->whereIn('catitem_item.catitem_id', $cats)
                //->groupBy('items.id')
                //->having(DB::raw('count(*)'), '=', count($cats))
                ->select('items.id', 'items.name', 'items.price', 'items.slug', 'item_listing.listing_id', 'listings.name as listing_name', 'listings.slug as listing_slug')
                ->get();

1 个答案:

答案 0 :(得分:0)

请注意,尝试这样做的方式,每个项目可能会有多行(每个相关列表一次)。更好的方法是每个项目都有一系列列表。

如果您使用雄辩模型并且已正确设置关系,则可以尝试以下操作:

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