0

我是 laravel 的新手,面临雄辩的搜索查询问题。我有两个表assetsassets_maintenance. 当用户搜索时,它们与它们有关系,即资产模型中的assetshasMany属于资产维护模型中的资产,然后我输入以下代码来获取结果。assets_maintenanceassetsassets_maintenance

$data['reports'] = AssetMaintenance::with(['assets'])
    ->where('inspector_id',$tenant_inspector_id)
    ->where('maintenance_due_date','>=',Carbon::now()->startOfDay())
    ->whereHas('assets',function($query){
        $query->active();//is_delete=0
    })
    ->whereHas('assets',function($query) use($stext){
        $query->where('asset_reference','like',"%{$stext}%")
                ->orWhere('asset_detail','like',"%{$stext}%");

    })
    ->orWhereHas('assets.assetCategory',function($query) use($stext){
        $query->where('assets_category.name','like',"%{$stext}%");
    })
    ->orWhere('maintenance_due_date','like',"%{$stext}%")
    ->orWhere('maintenance_cost','like',"%{$stext}%")
    ->orderBy('maintenance_due_date','ASC')
    // ->toSql();
    ->paginate(10);

但它没有给我正确的结果。有时它给了我另一个资产或检查员的记录。我想要结果,从哪里inspector_id=?manitenance_due_date大于now并且assets是活动的意味着不被删除。

其他条件可选asset_reference, asset_detail, assets_category.name, maintenance_due_date,maintenance_cost

在此处输入图像描述

在此处输入图像描述

4

2 回答 2

0

试试这个

$data['reports'] = AssetMaintenance::whereHas('assets',function($query) use($stext){
     $query->active()  //is_delete=0
     $query->where('asset_reference','like',"%{$stext}%")
            ->orWhere('asset_detail','like',"%{$stext}%");
})
->where('inspector_id',$tenant_inspector_id)
->where('maintenance_due_date','>=',Carbon::now()->startOfDay())
->orWhereHas('assets.assetCategory',function($query) use($stext){
    $query->where('assets_category.name','like',"%{$stext}%");
})
->orWhere('maintenance_due_date','like',"%{$stext}%")
->orWhere('maintenance_cost','like',"%{$stext}%")
->orderBy('maintenance_due_date','ASC')
// ->toSql();
->paginate(10);
于 2019-03-08T12:30:42.760 回答
0

这是一种误解优先级的情况,在语言&& / AND中总是会在|| / OR. 这意味着作为示例,您的查询inspector_id == x AND maintenance_due_date >= Now() AND maintenance_due_date like %text%或维护成本的较短版本,如 %text% can be true if only maintenance cost is liketext`。因为该语句将像这样被评估。

inspector_id == x AND maintenance_due_date >= Now() AND maintenance_due_date like %text%` OR maintenance_cost like %text%

将相等的语句转换为其值

false AND false AND false OR true

因为 AND 具有更高的优先级,所以它们首先得到评估。

false OR true

最后评估为真,或者在其他情况下,如果某些搜索为真,您可以找到未链接到特定检查器的元素。

将您的搜索逻辑包装在子 where 子句中,将获得您想要的结果。

$data['reports'] = AssetMaintenance::with(['assets'])
    ->where('inspector_id',$tenant_inspector_id)
    ->where('maintenance_due_date','>=',Carbon::now()->startOfDay())
    ->whereHas('assets',function($query){
        $query->active();//is_delete=0
    })

    //here is the extra where

    ->where(function($query){
        $query->whereHas('assets',function($query) use($stext){
        $query->where('asset_reference','like',"%{$stext}%")
                ->orWhere('asset_detail','like',"%{$stext}%");

        })
    ->orWhereHas('assets.assetCategory',function($query) use($stext){
        $query->where('assets_category.name','like',"%{$stext}%");
    })
    ->orWhere('maintenance_due_date','like',"%{$stext}%")
    ->orWhere('maintenance_cost','like',"%{$stext}%")
    ->orderBy('maintenance_due_date','ASC');
    })

    ->paginate(10);

现在,这将包装与搜索相关的 where 语句,因此将存在正确的优先级,再次简短示例:inspector_id == x AND (maintenance_due_date like %text% OR maintenance_cost like %text%)

于 2019-03-08T15:29:55.250 回答