Saya mencari solusi untuk menyaring pekerjaan berdasarkan gaji. Saya memiliki model Job yang memiliki 2 kolom min_salary dan max_salary, dan pengguna akan menggunakan penggeser untuk memilih dua nilai sebagai gaji minimum dan maksimum. Saya telah mencoba whereBetween dan orWhereBetween tetapi masalahnya adalah kueri ditutup dan saya tidak dapat melanjutkan dengan filter lain, jadi saya mencoba untuk mendapatkan rata-rata antara gaji min/maks model dan menggunakannya bukannya dua gaji.

Inilah yang saya coba:

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

Solusi ini tidak berfungsi seperti yang saya inginkan, karena saya tidak dapat melanjutkan dengan filter lain. Saya juga mencoba melakukan fungsi orWhere khusus dan melakukan kueri whereBetween yang terpisah, tetapi saya mendapatkan hasil yang sama.

Apa yang saya coba sekarang adalah untuk mendapatkan rata-rata antara model gaji maks dan min tanpa membuat bidang lain*, dan kemudian melanjutkan untuk melakukan sesuatu seperti itu:

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

Saya menghargai bantuan apa pun dengan solusi apa pun yang tidak memerlukan pembuatan bidang lain dalam database, dan saya tidak akan keberatan dengan solusi mentah sql jika berhasil.

Terima kasih.

Memperbarui

Inilah seluruh fungsi yang Anda miliki:

 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())
    ]);

Masalahnya adalah saya hanya ingin filter gaji bekerja dengan cara ini: katakanlah pengguna memilih dua nilai: $min dan $max (akan disimpan dalam array)

Sekarang saya ingin menunjukkan kepadanya pekerjaan di mana min_salary antara [$min, $max] atau max_salary antara [$min, $max].

NB : jika saya menggunakan :

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

Tanpa or itu berfungsi dengan baik, tetapi saya ingin logika or diimplementasikan.

1
khllifi zakaria 30 Januari 2020, 15:52

2 jawaban

Jawaban Terbaik

Anda perlu membatasi or ke 2 kondisi tersebut saja:

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

Untuk memahami mengapa ini diperlukan, Anda perlu mempertimbangkan kueri sql yang dihasilkan oleh fasih.

Jika Anda menulis:

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

Kueri yang dihasilkan akan menjadi:

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

Namun dalam SQL, operator AND lebih diutamakan daripada OR, sehingga kondisi secara logika dianggap seperti ini:

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

Ini bukan perilaku yang Anda inginkan.

Dengan melingkupi kondisi OR dalam penutupan where, pada dasarnya Anda memberi tahu fasih untuk menambahkan tanda kurung di sekitar kondisi, jadi:

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

Hasil dalam kueri berikut:

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

Yang mana yang diinginkan

0
gbalduzzi 30 Januari 2020, 14:18

Oke, terima kasih telah memperbarui pertanyaannya. Saya cukup yakin saya tidak dapat menjawabnya sekaligus, tetapi saya akan melakukan yang terbaik.

Sejauh yang saya bisa lihat, Anda bekerja di situs Pekerjaan di mana Anda ingin mengizinkan pengguna untuk memasukkan filter, dan hanya menampilkan pekerjaan yang cocok dengan filter tersebut.

Saya melihat Anda memiliki filter untuk gaji min/maks, jarak, gelar, kategori, dan jenis.

Anda juga memiliki kunci hs yang memutuskan tampilan mana yang akan dibuka dengan data mana.

Saya akan menganggap gaji min/maks sebagai pernyataan OR, dan sisanya AND.

Kalau begitu aku akan melakukannya

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

Jadi Anda bisa melakukan $mainQuery->where('anothermust-have', $somevalue);

0
Rob Biermann 30 Januari 2020, 13:55