Laravel中如何通过子表查询父表数据
Laravel中如何通过子表查询父表数据
嘿,这个需求我太熟了!在Laravel里完全不用写复杂的原生SQL JOIN就能优雅实现,当然如果你偏好JOIN的思路也有对应的封装方法,下面给你两种常用的方案:
一、利用Eloquent关联关系向上访问(最推荐)
首先得确保你的模型之间已经正确定义了反向关联,也就是从子模型指向父模型的关系:
- 先在
Product模型里定义和Store的关联:
// app/Models/Product.php public function store() { return $this->belongsTo(Store::class); }
- 然后在
Store模型里定义和Location的关联:
// app/Models/Store.php public function location() { return $this->belongsTo(Location::class); }
这样一来,你就能直接通过Product实例链式访问到对应的Location了:
// 获取单个Product的Location $product = Product::find(1); $location = $product->store->location; // 如果要批量查询,记得用预加载避免N+1查询问题 $products = Product::with('store.location')->get(); foreach ($products as $product) { echo $product->store->location->name; }
小贴士:预加载
with('store.location')能让Laravel只执行3次SQL查询(查所有Product,查对应的Store,查对应的Location),比循环里逐个查高效太多!
二、使用Laravel查询构造器写JOIN(和原生PHP逻辑一致)
如果你习惯用JOIN的思路,Laravel的查询构造器也封装了原生JOIN的能力,写法更简洁:
方法1:用DB门面直接写
$locations = DB::table('products') ->join('stores', 'products.store_id', '=', 'stores.id') ->join('locations', 'stores.location_id', '=', 'locations.id') ->where('products.id', '=', 1) // 可以根据需求加条件 ->select('locations.*') // 指定要获取的Location字段 ->first();
方法2:用Eloquent模型结合JOIN
$location = Product::join('stores', 'products.store_id', '=', 'stores.id') ->join('locations', 'stores.location_id', '=', 'locations.id') ->where('products.id', 1) ->select('locations.*') ->first();
两种方案各有优势:Eloquent关联更贴合Laravel的ORM设计,代码可读性高;JOIN查询则适合需要更复杂筛选或者追求极致性能的场景,你可以根据自己的需求选~
备注:内容来源于stack exchange,提问作者leouie tabique
相关产品推荐
相关产品推荐

