如何在Laravel查询代码中添加OUTER APPLY关联查询?
在Laravel中实现OUTER APPLY查询的两种方案
嗨,刚好我之前处理过类似的需求,针对你要实现的OUTER APPLY(或子查询作为字段)的查询,这里有两种适配Laravel的可行方案,完美匹配你给出的SQL示例:
方案一:使用selectRaw添加子查询字段
这种方式对应你给出的第一个SQL写法,直接把获取picname的子查询作为字段嵌入SELECT语句,实现起来最简单:
$data_result = tableA_model::selectRaw("*, (select top 1 name from imglist where id = tableA.id order by cover desc) as picname") ->where(function($query) use ($input) { $query->where('city', '=', $input['city']); }) ->get();
说明:
selectRaw()允许我们直接传入原生SQL片段,这里的子查询会为tableA的每一行匹配imglist中cover排序最靠前的第一条记录的name,并命名为picname。- 如果
imglist中没有匹配tableA.id的记录,picname会返回NULL,和OUTER APPLY的效果一致。
方案二:手动构造OUTER APPLY关联
如果你更倾向于使用OUTER APPLY的语法结构,可以通过Laravel的joinRaw()方法直接拼接原生关联语句,对应你给出的第二个SQL示例:
$data_result = tableA_model::select('tableA.*', 'img.picname') ->joinRaw('outer apply (select top 1 name as picname from imglist where id = tableA.id order by cover desc) img') ->where(function($query) use ($input) { $query->where('city', '=', $input['city']); }) ->get();
说明:
joinRaw()可以让我们直接使用数据库原生的关联语法,这里的outer apply会关联子查询结果,即使子查询没有匹配记录,主表tableA的行也会被保留,picname字段为NULL。- 如果你的数据库是MySQL(不支持OUTER APPLY),只需要把
outer apply替换为left join lateral即可,逻辑完全一致。
小提示
如果你的tableA_model中已经定义了$table属性(比如protected $table = 'tableA';),也可以用tableA_model::getTable()来动态获取表名,避免硬编码,让代码更健壮:
$tableName = tableA_model::getTable(); $data_result = tableA_model::selectRaw("*, (select top 1 name from imglist where id = {$tableName}.id order by cover desc) as picname") ->where(...) ->get();
内容的提问来源于stack exchange,提问作者Hao Han
相关产品推荐
相关产品推荐

