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

Laravel 7:如何优化排除客户已选服务的查询逻辑?

Laravel 查询逻辑优化:排除客户已关联服务

原问题背景

Measurement 表结构

idcustomer_idservice_id
112
213
22

原控制器代码

$customer = Customer::findOrFail($id);
$ex = Measurement::where('customer_id', $id)->pluck('service_id');
if(count($ex) == 0){
  $service = Service::where('status', 0)->get();
}
else{
  $service = Service::where('id', '!=', $ex)->where('status', 0)->get();
}

原逻辑:客户无关联service_id时返回所有status=0的服务;有则返回排除已关联ID且status=0的服务。

优化实现方案

方案一:简化条件判断,修复多值排除逻辑

原代码中where('id', '!=', $ex)存在逻辑问题——当$ex是多ID集合时,!=无法正确处理多值排除,改用whereNotIn,同时用Laravel的when()方法替代分支判断,让代码更简洁:

$customer = Customer::findOrFail($id);
// 过滤空的service_id,避免无效值干扰查询
$excludedIds = Measurement::where('customer_id', $id)
    ->whereNotNull('service_id')
    ->pluck('service_id');

$services = Service::where('status', 0)
    ->when($excludedIds->isNotEmpty(), function ($query) use ($excludedIds) {
        $query->whereNotIn('id', $excludedIds);
    })
    ->get();

方案二:利用模型关联简化代码(需提前定义关联)

如果Customer模型已和Measurement模型定义关联:

// Customer.php
public function measurements()
{
    return $this->hasMany(Measurement::class);
}

可以直接通过关联获取排除ID,代码更直观:

$customer = Customer::findOrFail($id);
$excludedIds = $customer->measurements()
    ->whereNotNull('service_id')
    ->pluck('service_id');

$services = Service::where('status', 0)
    ->when($excludedIds->isNotEmpty(), fn($q) => $q->whereNotIn('id', $excludedIds))
    ->get();

优化点说明

  1. 修复多值排除逻辑:用whereNotIn替代!=,正确处理多个ID的排除需求
  2. 过滤无效值:增加whereNotNull('service_id'),避免将Measurement表中为空的service_id作为排除条件
  3. 简化代码结构:用when()方法替代if-else分支,让查询逻辑连贯易读

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:20:28