Laravel在min-max过滤器中找到最小 - 最大工资的一部分

问题描述 投票:0回答:5

在DB我有一个User表,有2列:minSalarymaxSalary;

在搜索页面,我有一个薪水过滤器。所以这是一个2分输入类型范围。

<input type="range" name="minSalary" min="0" max="100000" value="3000">
<input type="range" name="maxSalary" min="0" max="100000" value="10000">

应用该过滤器时,它将转到该Controller路径:

$query = User::query();
... //another filters 
        if($request['minSalary'] && $request['maxSalary'])
        {
          $minFilter = (int) $request['minSalary'];
          $maxFilter = (int) $request['maxSalary'];

          $query->whereBetween('minSalary',   [ $minFilter, $maxFilter ])
          ->orWhere(function($query) use ($minFilter,$maxFilter) {
            $query->whereBetween('maxSalary',   [ $minFilter, $maxFilter ]);

          });

        }

我们注意:

minSalarymaxSalaryUser表中的列,$minFilter$maxFilter来自$_REQUEST

该查询检查最小工资是否在最小和最大过滤器之间,或者最大工资是否在最小和最大过滤器之间。

现在一些例子:过滤器:3000 - 10000 约翰:3500-5500 - 是一场比赛 Dave:2600 - 4100 - 是一个匹配,因为maxSalary(4100)介于3000-10000之间 Irene:7600-11000 - 是一个匹配<因为minSalary(7600)在3000-10000之间 安德鲁:2000-11000 - 不是匹配,但必须是我的逻辑和项目要求。

所以,我发现如果我要添加一个额外的条件:如果$minFilter介于minSalarymaxSalary之间或者$maxFilter介于minSalarymaxSalary之间,它会正常工作。

它必须看起来像:

  $query->whereBetween($minFilter,   [ 'minSalary', 'maxSalary' ])
  ->orWhere(function($query) use ($minFilter,$maxFilter) {
    $query->whereBetween($maxFilter',   [ 'minSalary', 'maxSalary' ]);

  });

这个查询必须如何与上面的查询一起工作?

为清楚起见:已经完成并且有效:

$query = User::query();
... //another filters 
        if($request['minSalary'] && $request['maxSalary'])
        {
          $minFilter = (int) $request['minSalary'];
          $maxFilter = (int) $request['maxSalary'];

          $query->whereBetween('minSalary',   [ $minFilter, $maxFilter ])
          ->orWhere(function($query) use ($minFilter,$maxFilter) {
            $query->whereBetween('maxSalary',   [ $minFilter, $maxFilter ]);

          });


//NEED TO IMPLEMENT PSEUDOCODE BELOW TO CODE FROM ABOVE: 
 $query->whereBetween($minFilter,   [ 'minSalary', 'maxSalary' ])
  ->orWhere(function($query) use ($minFilter,$maxFilter) {
    $query->whereBetween($maxFilter',   [ 'minSalary', 'maxSalary' ]);

  });

        }

我的整个代码:

  $query = User::query();
        $query->whereIn('position', $arrOfTags);

    if($request['minAge'] && $request['maxAge']) {
      $maxYear = Carbon::Now()->subYear($request['minAge']);
      $minYear = Carbon::Now()->subYear($request['maxAge']);

      $query->whereBetween('birthdate', [$minYear, $maxYear]);
    }

    if($request['skill']) {
        $query->join('skills', 'cvs.id', '=', 'skills.cv_id')
              ->join('allskills', 'skills.allskills_id', '=', 'allskills.id')
              ->select('cvs.*', 'allskills.name AS skillName')
              ->whereIn('skills.allskills_id', $request['skill']);
    }

if ($request->minSalary && $request->maxSalary) {
    $query->where(function($q) {
        $q->where('minSalary', '>=', request('minSalary'))
          ->where('maxSalary', '<=', request('minSalary'));
    })
    ->orWhere(function($q) {
        $q->where('minSalary', '>=', request('maxSalary'))
          ->where('maxSalary', '<=', request('maxSalary'));
    });
}

$users = $query->distinct()->paginate(3);
php mysql sql laravel
5个回答
1
投票

我是如何找到这个解决方案的,但这很简单!我们并不需要这么多疯狂的条件,只需要一些时间来实现正确的数学逻辑。

if(isset($request['minFilter']) && isset($request['maxFilter'])) {
  $minFilter = (int) $request['minFilter'];
  $maxFilter = (int) $request['maxFilter'];

  $query->where(function($query) use ($minFilter,$maxFilter) {
      $query->where('maxSalary', '>' , $minFilter);
      $query->where('minSalary', '<',  $maxFilter);
  });
}

这种情况适用于超过50例的测试。所以,我并没有真正发现每个都不会被它覆盖。


0
投票

如果我理解正确,你想要这个:

if ($request->minSalary && $request->maxSalary) {
    $query->where(function($q) {
        $q->where('minSalary', '>=', request('minSalary'))
          ->where('maxSalary', '<=', request('minSalary'));
    })
    ->orWhere(function($q) {
        $q->where('minSalary', '>=', request('maxSalary'))
          ->where('maxSalary', '<=', request('maxSalary'));
    });
}

0
投票

我正在扩展@AlexeyMezenin的,可能你正在寻找这个 -

$query = $query->where((function ($q) use ($minFilter, $maxFilter) {
        $q->orWhereBetween('minSalary', [$minFilter, $maxFilter]);
        $q->orWhereBetween('maxSalary', [$minFilter, $maxFilter]);
    }))
        ->orWhere((function ($q) use ($minFilter, $maxFilter) {
            $q->orWhere(function ($p) use ($minFilter, $maxFilter) {
                $p->where('minSalary', '>=', $minFilter)
                    ->where('maxSalary', '<=', $minFilter);
            });
            $q->where(function ($p) use ($minFilter, $maxFilter) {
                $p->where('minSalary', '>=', $maxFilter)
                    ->where('maxSalary', '<=', $maxFilter);
            });
        }));

首先where clause检查minSalary必须在[$minFilter, $maxFilter]之间或maxSalary必须在[$minFilter, $maxFilter]之间。

并且second where clause检查$minFilter必须在[ 'minSalary', 'maxSalary']之间或$maxFilter必须在[ 'minSalary', 'maxSalary']之间。

并且查询使用where子句它意味着它的AND查询。


0
投票

试试这个

$query->where(function($q) use($minSalary, $maxSalary){
           $q->where('min_salary', '>=', $minSalary)
           ->orWhere('max_salary', '>=', $minSalary);
    }
    ->where('min_salary', '<=', $maxSalary)
    ->get()

它满足这四个约束1.约翰:3500-5500 - 是一个匹配,因为minSalary(3500)更大$ minSalary(3000)&minSalary(3500)<$ maxSalary(10000)

  1. Dave:2600 - 4100 - 是一个匹配,因为maxSalary(4100)更大$ minSalary(3000)&minSalary(2600)<$ maxSalary(10000)
  2. Irene:7600-11000 - 是一个匹配<因为minSalary(7600)更大$ minSalary(3000)&minSalary(7600)<$ maxSalary(10000)
  3. Andrew:2000-11000 - 是一个匹配,因为maxSalary(11000)更大$ minSalary(3000)&minSalary(2000)<$ maxSalary(10000)

它将限制其他无效范围。


0
投票

试试这个

$query->where(function($query) use($minSalary=0, $maxSalary=0){
if($minSalary){
$query->where('min_salary', '>=', $minSalary);
}
if($maxSalary){
$query->where('max_salary', '<=', $maxSalary);
}
})->get();
© www.soinside.com 2019 - 2024. All rights reserved.