如何将带子查询的MySQL语句转换为Laravel查询语法?
把你的MySQL查询转换为Laravel查询构造器语法
没问题,我来帮你把这条SQL转换成Laravel的查询构造器语法。先理清楚原SQL的核心逻辑:它先统计每个vd_id对应的销售数据条数,然后筛选出那些条数等于所有分组中最大值或者最小值的记录。
下面提供两种实现方式,你可以根据自己的需求选择:
方式一:先获取最大/最小值,再筛选(代码更清晰)
这种方式先单独查询出最大和最小的计数,再用这两个值去筛选分组后的结果,可读性更强:
// 1. 统计每个vd_id的销售数据条数,作为子查询 $subQuery = DB::table('sell_data') ->select('vd_id', DB::raw('count(vd_id) as subCount')) ->groupBy('vd_id'); // 2. 获取分组中的最大计数 $maxCount = DB::table('sell_data') ->select(DB::raw('count(vd_id) as maxCount')) ->groupBy('vd_id') ->orderByDesc('maxCount') ->limit(1) ->value('maxCount'); // 3. 获取分组中的最小计数 $minCount = DB::table('sell_data') ->select(DB::raw('count(vd_id) as minCount')) ->groupBy('vd_id') ->orderByAsc('minCount') ->limit(1) ->value('minCount'); // 4. 筛选出计数等于最大或最小的记录 $result = DB::table($subQuery, 'sub') ->select('vd_id', 'subCount') ->where('subCount', $maxCount) ->orWhere('subCount', $minCount) ->get();
方式二:完全嵌套子查询(和原SQL结构一致)
如果你想完全对应原SQL的嵌套结构,不需要单独查询最大/最小值,可以把所有子查询直接嵌套在主查询中:
$result = DB::table(function ($query) { // 内层子查询:统计每个vd_id的计数 $query->from('sell_data') ->select('vd_id', DB::raw('count(vd_id) as subCount')) ->groupBy('vd_id'); }, 'sub') ->select('vd_id', 'subCount') ->where(function ($whereClause) { // 条件1:计数等于分组中的最大值 $whereClause->where('subCount', function ($maxQuery) { $maxQuery->from('sell_data') ->select(DB::raw('count(vd_id)')) ->groupBy('vd_id') ->orderByDesc(DB::raw('count(vd_id)')) ->limit(1); }) // 条件2:计数等于分组中的最小值 ->orWhere('subCount', function ($minQuery) { $minQuery->from('sell_data') ->select(DB::raw('count(vd_id)')) ->groupBy('vd_id') ->orderByAsc(DB::raw('count(vd_id)')) ->limit(1); }); }) ->get();
额外说明:使用Eloquent模型的写法
如果你有对应的Eloquent模型(比如SellData),也可以用模型来编写查询,代码会更贴合Laravel的ORM风格:
use App\Models\SellData; $result = SellData::from(function ($query) { $query->from('sell_data') ->select('vd_id', DB::raw('count(vd_id) as subCount')) ->groupBy('vd_id'); }, 'sub') ->select('vd_id', 'subCount') ->where('subCount', SellData::select(DB::raw('count(vd_id)')) ->groupBy('vd_id') ->orderByDesc(DB::raw('count(vd_id)')) ->limit(1)) ->orWhere('subCount', SellData::select(DB::raw('count(vd_id)')) ->groupBy('vd_id') ->orderByAsc(DB::raw('count(vd_id)')) ->limit(1)) ->get();
需要注意的是,我们使用DB::raw()来处理聚合函数count(vd_id)以及排序的字段,因为Laravel的查询构造器默认会对字段名进行转义,直接写的话会导致语法错误。
内容的提问来源于stack exchange,提问作者Hajae
相关产品推荐
相关产品推荐

