Laravel красноречиво, как запросить avrege и сравнить его между двумя значениями - PullRequest
1 голос
/ 30 января 2020

Я ищу решение фильтровать работу, основываясь на зарплате. У меня есть модель Job, которая имеет 2 столбца min_salary и max_salary, и пользователь собирается использовать ползунок, чтобы выбрать два значения как минимальную и максимальную зарплату. Я пробовал whereBetween и orWhereBetween, но проблема в том, что запрос закрывается, и я не могу продолжить работу с другими фильтрами, поэтому пытаюсь получить среднее значение между минимальной / максимальной зарплатой модели и использовать его вместо двух slaries.

Вот что я попробовал:

  $salary = explode(',',$request->salary); // geting the salary range from the request as array
  $jobs  = Job::whereBetween('min_salary',$salary)->orWhereBetween('max_salary',$salary);

Это решение не работает так, как я хочу, так как я не могу продолжить работу с другими фильтрами. Я также пытался выполнить пользовательскую функцию orWhere и выполнять отдельные whereBetween запросы, но получил тот же результат.

Сейчас я пытаюсь получить среднее значение между максимальной и минимальной зарплатой модели без создание другого поля *, а затем приступить к выполнению чего-то подобного:

  $jobs  = Job::whereBetween('theCalculatedAvg',$salary);

Я ценю любую помощь с любым решением, которое не требует создания другого поля в базе данных, и я не против sql Необработанное решение, если оно выполняет свою работу.

Спасибо.

Обновление

Вот вся функция, которая у вас была:

 if($request->has('offset')) {

        $salary = explode(',',$request->salary);
        $jobs  = Job::whereBetween('min_salary',$salary)->orWhereBetween('max_salary',$salary);
        if ($request->has('lat')) {
            $sqlDistance = DB::raw
            ('
          ( 6371 * acos
              ( cos
                  ( radians
                      (' . $request->lat . ')
                  )
              * cos
                  ( radians
                      ( lat )
                  )
              * cos
                  ( radians
                      ( lon )
                  - radians
                      (' . $request->lon . ')
                  )
              + sin
                  ( radians
                      (' . $request->lat  . ')
                  )
              * sin
                  ( radians
                      ( lat )
                  )
              )
          )
        ');
            $jobs->when($sqlDistance != null, function ($query) use ($sqlDistance,$request){
                $query->whereHas('address', function ($subQuery) use ($sqlDistance,$request) {
                    $subQuery->addSelect(DB::raw("{$sqlDistance} AS distance"));
                    $subQuery->havingRaw("distance <= ?", [(int)$request->range]);
                });
            })
                ->with('company')
                ->with('address');


        }

        if ($request->has('key')) {
            $jobs->where('title', 'like', '%' . $request->key . '%');
        }

        if ($request->has('cat')) {
            $cat = explode(',',$request->cat);

            $jobs->whereIn('category_id', $cat);
        }

        if ($request->has('type')) {
            $type = explode(',',$request->type);

            $jobs->whereIn('type', $type);
        }

        if($request->has('hs')) {

            return view("General::browseJobs", [
                'jobs' => $jobs->orderBy('created_at','desc')->skip($request->offset * 2)->take(2)->get(),
                'count' => count($jobs->get())
            ]);

        }

        $view = view('General::loaders.jobs', [
            'jobs' => $jobs->orderBy('created_at','desc')->skip($request->offset * 2)->take(2)->get()
        ])->render();

        return response()->json(['html' => $view , 'count' => count($jobs->get()) ]);

    }



    return view("General::browseJobs", [
        'jobs' => Job::orderBy('created_at','desc')->take(2)->get(),
        'count' => count(Job::all())
    ]);

Проблема в том, что я просто хочу, чтобы фильтр зарплаты работал следующим образом: допустим, пользователь выбрал два значения: $ min и $ max (будут храниться в массиве)

Теперь я хочу показать ему работу, где min_salary находится между [$ min, $ max] или max_salary между [$ min, $ max].

Примечание: если я использую:

Job::whereBetween('min_salary',$salary)->whereBetween('max_salary',$salary);

без или он работает нормально , но я хочу, чтобы или логика c была реализована.

Ответы [ 2 ]

0 голосов
/ 30 января 2020

Хорошо, спасибо за обновление вопроса. Я почти уверен, что не смогу ответить на него в один go, но я сделаю все возможное.

Насколько я понимаю, вы работаете над сайтом вакансий, где вы хотите разрешить пользователям вводить фильтры и показывать только задания, соответствующие этим фильтрам.

Я вижу, у вас есть фильтры для минимальной / максимальной зарплаты, расстояния, названия, категорий и типов.

У вас также есть клавиша hs, которая решает, какой вид открыть с какими данными.

Я бы посчитал минимальную / максимальную зарплату подтверждением ИЛИ, а остальные - AND.

В этом случае я бы сделал

$mainQuery = Job::where(function($query) use($salary)
{ 
    $query->whereBetween('min_salary', $salary)->orWhereBetween('max_salary', $salary);
});

Так что вы можете сделать $mainQuery->where('anothermust-have', $somevalue);

0 голосов
/ 30 января 2020

Вам нужно ограничить or только этими двумя условиями:

Jobs::where(function (q) use ($salary) {
  $q->whereBetween('min_salary',$salary)->orWhereBetween('max_salary',$salary);
})

Чтобы понять, почему это требуется, вам нужно рассмотреть запрос sql, созданный eloquent.

Если вы напишите:

$jobs = Jobs::where([condition1])->orWhere([condition2]);
.. some other code..
$jobs->where([condition3]);
...
$jobs->where([condition4]);

Результирующий запрос будет:

SELECT *
FROM jobs
WHERE [condition1] OR [condition2] AND [condition3] AND [condition4]

Но в SQL оператор AND имеет приоритет над OR, поэтому условия логически рассматривается следующим образом:

([condition1]) OR ([condition2] AND [condition3] AND [condition4])

Это не то поведение, которое вам нужно.

Определяя условие OR в замыкании where, вы в основном говорите eloquent добавить скобки вокруг условий, поэтому :

$jobs = Jobs::where(function ($q) {
 $q->where([condition1])->orWhere([condition2]);
});
.. some other code..
$jobs->where([condition3]);
...
$jobs->where([condition4]);

Результат в следующем запросе:

SELECT *
FROM jobs
WHERE ([condition1] OR [condition2]) AND [condition3] AND [condition4]

, который является желаемым

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...