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

如何在Laravel中执行多子查询并返回JSON结果?

解决方案:在Laravel中添加多个子查询并返回JSON

方法一:多次调用addSelect添加多个子查询

你之前的代码只加了一个子查询,要加多个的话,直接在addSelect的数组里新增键值对即可,每个键对应返回的字段名,值是对应的子查询。注意子查询必须返回单个结果,所以limit(1)是必需的(你之前写的limit(6)会导致报错,因为一台机器只对应一个显卡ID)。

示例代码:

return Machines::addSelect([
    // 显卡名称
    'graphic_card_name' => GraphicCard::select('name')
        ->whereColumn('id', 'machines.graphicCardId')
        ->limit(1),
    // CPU名称(假设存在Cpu模型)
    'cpu_name' => Cpu::select('name')
        ->whereColumn('id', 'machines.cpuId')
        ->limit(1),
    // 内存类型(假设存在Memory模型)
    'memory_type' => Memory::select('type')
        ->whereColumn('id', 'machines.memoryId')
        ->limit(1)
])->get();

方法二:利用Model关联+预加载(更优雅)

如果你的Model已经定义了关联关系,用with()预加载关联数据会更简洁,还能避免N+1查询问题。

  1. 先在Machines模型里定义关联:
// app/Models/Machines.php
public function graphicCard()
{
    // 第二个参数是Machines表的外键字段
    return $this->belongsTo(GraphicCard::class, 'graphicCardId');
}

public function cpu()
{
    return $this->belongsTo(Cpu::class, 'cpuId');
}
  1. 查询时预加载关联,并整理成需要的JSON结构:
$machines = Machines::with(['graphicCard:id,name', 'cpu:id,name'])->get();

// 整理成自定义JSON结构
$formattedMachines = $machines->map(function ($machine) {
    return [
        'id' => $machine->id,
        'machine_name' => $machine->name,
        'graphic_card' => $machine->graphicCard?->name ?? '无对应显卡',
        'cpu' => $machine->cpu?->name ?? '无对应CPU',
        // 其他需要的字段
    ];
});

return response()->json($formattedMachines);

在Blade模板中的使用方式

如果要在Blade里直接渲染数据,控制器将变量传入视图:

// 控制器
$machines = Machines::addSelect([...])->get();
return view('machines.list', compact('machines'));

Blade模板里遍历渲染:

@foreach($machines as $machine)
    <div class="machine-item">
        <h3>{{ $machine->name }}</h3>
        <p>显卡:{{ $machine->graphic_card_name ?? '未配置' }}</p>
        <p>CPU:{{ $machine->cpu_name ?? '未配置' }}</p>
    </div>
@endforeach

关于DB::raw()的正确写法

如果你一定要用DB::raw(),需要把整个子查询用括号包裹,示例:

return Machines::addSelect([
    'graphic_card_name' => DB::raw('(SELECT name FROM graphic_cards WHERE id = machines.graphicCardId LIMIT 1)'),
    'cpu_name' => DB::raw('(SELECT name FROM cpus WHERE id = machines.cpuId LIMIT 1)')
])->get();

不过这种写法可读性差,不如Eloquent子查询直观,不推荐。

内容的提问来源于stack exchange,提问作者laravel_

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 06:05:56