You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eloquent技术问询:获取拥有至少一条广告的用户

嘿,我来帮你搞定这个查询的问题~ 先从你的原SQL说起,再给你对应的Eloquent实现,顺便优化一下写法:

原SQL的优化点

你的原SQL确实能实现需求,但存在冗余逻辑:你已经用了INNER JOIN anuncio,这一步会自动过滤掉没有关联广告的用户(因为内连接只保留两边都有匹配数据的行),后面的WHERE (SELECT COUNT(*) ...) > 0完全是重复过滤,没必要保留。

优化后的精简SQL如下:

SELECT users.id, COUNT(anuncio.id) AS total 
FROM users 
INNER JOIN anuncio ON users.id = anuncio.usuario_id 
GROUP BY users.id

这个版本和原SQL结果完全一致,但执行效率更高。

基于User模型的Eloquent实现

假设你已经在User模型里定义了和Anuncio的一对多关联(注意模型名要符合Laravel的命名规范,一般是单数首字母大写):

// app/Models/User.php
public function anuncios()
{
    return $this->hasMany(Anuncio::class, 'usuario_id');
}

下面给你几种常用的Eloquent写法,按需选择:

写法1:最简洁的推荐写法(has() + withCount())

has('anuncios')会自动筛选出至少拥有一条广告的用户,withCount()用来统计每个用户的广告数量,代码可读性拉满:

$users = User::has('anuncios')
             ->withCount('anuncios as total')
             ->select('id')
             ->get();

Eloquent会自动帮你生成和优化后SQL一致的高效查询语句。

写法2:完全映射优化后SQL的写法(join() + groupBy())

如果你想完全手动对应SQL的逻辑,可以用join方式,需要引入DB门面:

use Illuminate\Support\Facades\DB;

$users = User::join('anuncio', 'users.id', '=', 'anuncio.usuario_id')
             ->select('users.id', DB::raw('COUNT(anuncio.id) as total'))
             ->groupBy('users.id')
             ->get();

写法3:支持额外过滤广告的场景(whereHas())

如果之后需要对广告加筛选条件(比如只统计已发布的广告),可以用whereHas():

$users = User::whereHas('anuncios', function($query) {
                // 这里可以添加广告的过滤条件,例如:
                // $query->where('status', 'published');
            })
            ->withCount('anuncios as total')
            ->select('id')
            ->get();
补充小提示
  • 如果你只需要获取有广告的用户,不需要统计数量,直接用User::has('anuncios')->get()就够了。
  • 确保Anuncio模型里的外键usuario_id和User模型的主键id对应正确,关联关系不要写错哦~

内容的提问来源于stack exchange,提问作者Santos Osmin Urrutia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:35:44