Eloquent QueryBuilder 是 Laravel 提供的数据库查询构造器,它提供了一种流畅、直观的方式来构建和执行数据库查询。子查询是指在一个查询中嵌套另一个查询,这在需要基于其他查询结果进行筛选或计算时非常有用。
场景:在主查询的 SELECT 部分使用子查询计算结果
$users = DB::table('users')
->select([
'users.*',
DB::raw('(SELECT COUNT(*) FROM posts WHERE posts.user_id = users.id) as post_count')
])
->get();
场景:在 WHERE 条件中使用子查询
$popularPosts = DB::table('posts')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('comments')
->whereRaw('comments.post_id = posts.id')
->where('comments.rating', '>', 4);
})
->get();
场景:将子查询结果作为临时表
$latestPosts = DB::table(function ($query) {
$query->from('posts')
->select('user_id', DB::raw('MAX(created_at) as latest_post'))
->groupBy('user_id');
}, 'latest_posts')
->join('users', 'users.id', '=', 'latest_posts.user_id')
->select('users.name', 'latest_posts.latest_post')
->get();
场景:在 JOIN 中使用子查询
$usersWithLatestPost = DB::table('users')
->leftJoinSub(
DB::table('posts')
->select('user_id', DB::raw('MAX(created_at) as latest_post'))
->groupBy('user_id'),
'latest_posts',
'users.id',
'=',
'latest_posts.user_id'
)
->get();
原因:复杂的子查询可能导致性能下降
解决方案:
->toSql()
检查生成的 SQL 并进行优化原因:子查询中无法访问外部查询的变量
解决方案:
use
关键字传递变量到闭包$minRating = 4;
$posts = DB::table('posts')
->whereExists(function ($query) use ($minRating) {
$query->select(DB::raw(1))
->from('comments')
->whereRaw('comments.post_id = posts.id')
->where('comments.rating', '>', $minRating);
})
->get();
原因:多层嵌套子查询难以维护
解决方案:
tap
函数提高可读性$users = User::select([
'users.*',
DB::raw('(SELECT COUNT(*) FROM posts WHERE posts.user_id = users.id) as post_count'),
DB::raw('(SELECT AVG(rating) FROM comments WHERE comments.user_id = users.id) as avg_rating')
])
->orderByDesc('post_count')
->get();
$searchTerm = 'Laravel';
$posts = Post::where(function ($query) use ($searchTerm) {
$query->where('title', 'like', "%{$searchTerm}%")
->orWhereHas('comments', function ($query) use ($searchTerm) {
$query->where('content', 'like', "%{$searchTerm}%");
});
})
->withCount(['comments as popular_comments' => function ($query) {
$query->where('rating', '>', 4);
}])
->get();
通过以上方法和示例,您可以在 Laravel 中灵活使用 Eloquent QueryBuilder 构建各种复杂的子查询。
没有搜到相关的文章