Laravel如何使用Eloquent进行子查询
发布时间 - 2025-12-01 00:00:00 点击率:次Laravel Eloquent支持子查询,可通过addSelect获取用户最新订单时间,where条件中嵌套查询筛选订单总额超1000的用户,joinSub将子查询结果作为临时表连接,或使用withSum等快捷方法预加载聚合数据,提升复杂查询可读性与效率。
在 Laravel 中,Eloquent 支持通过子查询(Subquery)来实现更复杂的查询逻辑。你可以将一个查询的结果作为另一个查询的字段或条件使用,尤其适用于获取关联数据中的最新记录、统计值等场景。下面介绍几种常见的使用方式。
在 SELECT 中使用子查询
如果你想在查询结果中包含一个来自子查询的字段,比如获取每个用户的最后一条订单信息,可以这样做:
假设你有 User 模型和 Order 模型,你想查出每个用户的名字和他们最近订单的创建时间。
use Illuminate\Database\Eloquent\Builder;
$users = User::select('users.*')
->addSelect(['last_order_at' => Order::select('created_at')
->whereColumn('user_id', 'users.id')
->orderByDesc('created_at')
->limit(1)
]
)
->get();
这里使用了 addSelect() 添加一个子查询字段,该子查询获取当前用户最新的订单时间。
在 WHERE 条件中使用子查询
你可以用子查询作为 WHERE 的判断条件。例如:找出订单总额超过 1000 的用户。
$totalQuery = Order::selectRaw('sum(amount)')
->whereColumn('user_id', 'users.id');
$users = User::whereHas('orders')
->where(function (Builder $query) use ($totalQuery) {
$query->select($totalQuery)->from('orders')->limit(1)->shouldAllowSelfJoins()
}, '>', 1000)
->get();
也可以更简洁地写成:
$users = User::whereExists(function ($query) {
$query->select(DB::raw(1))
->from('orders')
->whereColumn('orders.user_id', 'users.id')
->havingRaw('sum(amount) > 1000')
->groupBy('orders.user_id');
})->get();
在 JOIN 中使用子查询
有时你需要将子查询作为一个临时表进行 JOIN。例如获取每个用户的最新一条订单。
$latestOrderSubquery = Order::select('user_id', DB::raw('max(created_at) as last_order_at'))
->groupBy('user_id');
$users = User::joinSub($latestOrderSubquery, 'latest_orders', function ($join) {
$join->on('users.id', '=', 'latest_orders.user_id');
})->get();
joinSub() 方法允许你把一个查询当作一个子查询表来 JOIN,非常适用于聚合或去重场景。
使用 withSum、withMax 等快捷方法(Laravel 8+)
Laravel 提供了一些便捷的预加载子查询方法,如 withSum、withMax、withAvg 等。
// 获取用户及其订单总金额
$users = User::withSum('orders as total_spent', 'amount')->get();
foreach ($users as $user) {
echo $user->total_spent; // 直接访问
}
这种方式比手动写子查询更清晰,适合简单的聚合场景。
基本上就这些。Laravel 的 Eloquent 子查询功能强大且灵活,合理使用能让复杂查询变得简洁易懂。关键在于理解何时使用 selectSub、joinSub 或内置的 withXxx 方法。不复杂但容易忽略细节,比如别名定义和作用域绑定。
# laravel
# 作用域
# select
# 适用于
# 你想
# 查询结果
# 加载
# 你可以
# 可以用
# 你有
# 能让
# 这样做
# 几种
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何为不同团队 ID 动态生成多个“认领值班”按钮
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】
微信h5制作网站有哪些,免费微信H5页面制作工具?
如何快速辨别茅台真假?关键步骤解析
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
Laravel如何生成URL和重定向?(路由助手函数)
Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
Android中AutoCompleteTextView自动提示
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
微信推文制作网站有哪些,怎么做微信推文,急?
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
如何在景安服务器上快速搭建个人网站?
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
html5如何实现懒加载图片_ intersectionobserver api用法【教程】
如何在云指建站中生成FTP站点?
网站制作报价单模板图片,小松挖机官方网站报价?
ChatGPT 4.0官网入口地址 ChatGPT在线体验官网
Android滚轮选择时间控件使用详解
重庆市网站制作公司,重庆招聘网站哪个好?
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
iOS中将个别页面强制横屏其他页面竖屏
Python进程池调度策略_任务分发说明【指导】
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
如何在宝塔面板创建新站点?
详解Android——蓝牙技术 带你实现终端间数据传输
Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
昵图网官方站入口 昵图网素材图库官网入口
如何确保FTP站点访问权限与数据传输安全?
Python文件流缓冲机制_IO性能解析【教程】
如何用PHP快速搭建高效网站?分步指南
如何在腾讯云服务器上快速搭建个人网站?
UC浏览器如何设置启动页 UC浏览器启动页设置方法
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
Python自动化办公教程_ExcelWordPDF批量处理案例
Laravel如何实现API速率限制?(Rate Limiting教程)
如何用AWS免费套餐快速搭建高效网站?
制作公司内部网站有哪些,内网如何建网站?
Android 常见的图片加载框架详细介绍
,在苏州找工作,上哪个网站比较好?
Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】
如何快速搭建二级域名独立网站?
Android okhttputils现在进度显示实例代码
如何在IIS中新建站点并解决端口绑定冲突?
Laravel如何发送系统通知?(Notification渠道示例)
Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】


)
->get();