Laravel Eloquent模型自定义关联:广告与价格区间关联查询实现
没问题!我来一步步帮你配置Eloquent模型,完美实现你要的所有功能,完全对应你提到的原生SQL效果~
实现Eloquent模型关联与统计功能
1. 先定义基础模型
首先创建两个对应数据表的Eloquent模型:
Advert模型
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Advert extends Model { protected $table = 'adverts'; protected $fillable = ['price', 'status']; // 这里补充你的其他字段 }
Pricerange模型
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Pricerange extends Model { protected $table = 'priceranges'; protected $fillable = ['price_from', 'price_to']; // 补充你的其他字段 }
2. 从Pricerange实例获取匹配广告
在Pricerange模型里定义一个关联方法,直接获取该价格区间下的所有匹配广告:
public function adverts() { return $this->hasMany(Advert::class) ->where('price', '>=', $this->price_from) ->where('price', '<=', $this->price_to); }
使用的时候非常简单,直接通过实例调用关联即可:
// 获取ID为1的价格区间对应的所有广告 $pricerange = Pricerange::find(1); $matchingAdverts = $pricerange->adverts;
如果需要添加额外筛选条件(比如只看活跃广告),直接链式追加where就行:
$activeAdverts = $pricerange->adverts()->where('status', 'active')->get();
3. 查询价格区间并统计匹配广告数量
要实现等效于你给出的原生SQL子查询统计,有两种清晰的实现方式:
方法一:使用selectSub(推荐,代码可读性更高)
use App\Models\Pricerange; $pricerangesWithCount = Pricerange::select('*') ->selectSub(function ($query) { $query->selectRaw('COUNT(id)') ->from('adverts') ->whereColumn('adverts.price', '>=', 'priceranges.price_from') ->whereColumn('adverts.price', '<=', 'priceranges.price_to'); }, 'advert_count') ->get();
方法二:直接写入原生子查询字符串(和你给出的SQL结构完全一致)
$pricerangesWithCount = Pricerange::select('priceranges.*', '( SELECT COUNT(adverts.id) FROM adverts WHERE adverts.price >= priceranges.price_from AND adverts.price <= priceranges.price_to ) as advert_count') ->get();
两种方式都会让每个Pricerange实例带上advert_count属性,就是该区间匹配的广告总数。
4. 给统计添加更多自定义条件
如果需要在统计时加入额外筛选(比如只统计审核通过的广告),直接在子查询里追加条件即可:
$pricerangesWithApprovedCount = Pricerange::select('*') ->selectSub(function ($query) { $query->selectRaw('COUNT(id)') ->from('adverts') ->whereColumn('adverts.price', '>=', 'priceranges.price_from') ->whereColumn('adverts.price', '<=', 'priceranges.price_to') ->where('adverts.is_approved', true); // 这里添加你的额外条件 }, 'approved_advert_count') ->get();
你也可以通过定义带条件的关联,再用withCount来实现:
// 先在Pricerange模型里定义带筛选的关联 public function approvedAdverts() { return $this->adverts()->where('is_approved', true); } // 然后直接统计 $pricerangesWithApprovedCount = Pricerange::withCount('approvedAdverts')->get(); // 此时每个实例的approved_adverts_count属性就是统计结果
这样所有需求就都完美实现了,不管是获取匹配广告、统计数量还是添加自定义筛选,都能轻松搞定~
内容的提问来源于stack exchange,提问作者peterkin
相关产品推荐
相关产品推荐

