Bagaimana Cara Membuat Beberapa Query Klausa Dimana Menggunakan Laravel Eloquent?


406

Saya menggunakan pembuat kueri Laravel Eloquent dan saya punya permintaan di mana saya ingin WHEREklausa pada beberapa kondisi. Ini bekerja, tetapi tidak elegan.

Contoh:

$results = User::where('this', '=', 1)
    ->where('that', '=', 1)
    ->where('this_too', '=', 1)
    ->where('that_too', '=', 1)
    ->where('this_as_well', '=', 1)
    ->where('that_as_well', '=', 1)
    ->where('this_one_too', '=', 1)
    ->where('that_one_too', '=', 1)
    ->where('this_one_as_well', '=', 1)
    ->where('that_one_as_well', '=', 1)
    ->get();

Apakah ada cara yang lebih baik untuk melakukan ini, atau haruskah saya tetap menggunakan metode ini?


4
Ada banyak kemungkinan dalam hal bagaimana hal ini dapat disederhanakan, tetapi itu membutuhkan beberapa kode yang lebih realistis. Bisakah Anda memperbarui kode menjadi sedikit lebih realistis? Misalnya, ada kalanya beberapa ->where(...)panggilan dapat diganti dengan ->whereIn(...)panggilan, dan sebagainya .
jonathanmarvens

2
Solusi @Jarek Tkaczyk harus menjadi jawabannya, saya setuju. Tapi saya lebih suka kode Anda seperti skrip pembangun untuk pemahaman dan pemeliharaan.
Tiefan Ju

Jawaban:


620

Di Laravel 5.3 (dan masih berlaku pada 7.x ) Anda bisa menggunakan lebih banyak butiran granular yang dilewatkan sebagai array:

$query->where([
    ['column_1', '=', 'value_1'],
    ['column_2', '<>', 'value_2'],
    [COLUMN, OPERATOR, VALUE],
    ...
])

Secara pribadi saya belum menemukan use case untuk ini lebih dari beberapa wherepanggilan, tetapi kenyataannya adalah Anda dapat menggunakannya.

Sejak Juni 2014 Anda dapat meneruskan larik ke where

Selama Anda menginginkan semua operator yang wheresdigunakan and, Anda dapat mengelompokkannya dengan cara ini:

$matchThese = ['field' => 'value', 'another_field' => 'another_value', ...];

// if you need another group of wheres as an alternative:
$orThose = ['yet_another_field' => 'yet_another_value', ...];

Kemudian:

$results = User::where($matchThese)->get();

// with another group
$results = User::where($matchThese)
    ->orWhere($orThose)
    ->get();

Di atas akan menghasilkan permintaan seperti itu:

SELECT * FROM users
  WHERE (field = value AND another_field = another_value AND ...)
  OR (yet_another_field = yet_another_value AND ...)

8
Bagaimana Anda menentukan operator?
Styphon

9
@Styphon Anda tidak. Saat ini hanya berfungsi dengan =.
Jarek Tkaczyk

5
@Styphon dan bagaimana jika saya ingin membuat: WHERE (a IS NOT NULL AND b=1) OR (a IS NULL AND b=2);?
alexglue

9
Anda juga dapat melewati serangkaian kondisi seperti ini:$users = DB::table('users')->where([ ['status', '=', '1'], ['subscribed', '<>', '1'], ])->get();
nol-dan-yang

3
@jarek: Bagaimana cara saya memasukkan whereNotInjawaban Anda sesuai dengan pertanyaan lain where?
Kalanka

93

Lingkup kueri dapat membantu Anda membuat kode Anda lebih mudah dibaca.

http://laravel.com/docs/eloquent#query-scopes

Memperbarui jawaban ini dengan beberapa contoh:

Di model Anda, buat metode cakupan seperti ini:

public function scopeActive($query)
{
    return $query->where('active', '=', 1);
}

public function scopeThat($query)
{
    return $query->where('that', '=', 1);
}

Kemudian, Anda dapat memanggil cakupan ini sambil membangun kueri Anda:

$users = User::active()->that()->get();

apa praktik terbaik untuk kondisi seperti ini, kueri-> di mana ('start_date'> $ startDate) apakah masih bisa menggunakan Lingkup?
Buwaneka Kalansuriya

72

Anda dapat menggunakan subquery dalam fungsi anonim seperti ini:

 $results = User::where('this', '=', 1)
            ->where('that', '=', 1)
            ->where(function($query) {
                /** @var $query Illuminate\Database\Query\Builder  */
                return $query->where('this_too', 'LIKE', '%fake%')
                    ->orWhere('that_too', '=', 1);
            })
            ->get();

43

Dalam hal ini Anda dapat menggunakan sesuatu seperti ini:

User::where('this', '=', 1)
    ->whereNotNull('created_at')
    ->whereNotNull('updated_at')
    ->where(function($query){
        return $query
        ->whereNull('alias')
        ->orWhere('alias', '=', 'admin');
    });

Itu seharusnya memberi Anda permintaan seperti:

SELECT * FROM `user` 
WHERE `user`.`this` = 1 
    AND `user`.`created_at` IS NOT NULL 
    AND `user`.`updated_at` IS NOT NULL 
    AND (`alias` IS NULL OR `alias` = 'admin')

36

Ketentuan menggunakan Array:

$users = User::where([
       'column1' => value1,
       'column2' => value2,
       'column3' => value3
])->get();

Akan menghasilkan kueri seperti di bawah ini:

SELECT * FROM TABLE WHERE column1=value1 and column2=value2 and column3=value3

Kondisi menggunakan Fungsi Antonim:

$users = User::where('column1', '=', value1)
               ->where(function($query) use ($variable1,$variable2){
                    $query->where('column2','=',$variable1)
                   ->orWhere('column3','=',$variable2);
               })
              ->where(function($query2) use ($variable1,$variable2){
                    $query2->where('column4','=',$variable1)
                   ->where('column5','=',$variable2);
              })->get();

Akan menghasilkan kueri seperti di bawah ini:

SELECT * FROM TABLE WHERE column1=value1 and (column2=value2 or column3=value3) and (column4=value4 and column5=value5)

12

Beberapa klausa tempat

    $query=DB::table('users')
        ->whereRaw("users.id BETWEEN 1003 AND 1004")
        ->whereNotIn('users.id', [1005,1006,1007])
        ->whereIn('users.id',  [1008,1009,1010]);
    $query->where(function($query2) use ($value)
    {
        $query2->where('user_type', 2)
            ->orWhere('value', $value);
    });

   if ($user == 'admin'){
        $query->where('users.user_name', $user);
    }

akhirnya mendapatkan hasilnya

    $result = $query->get();

9

The whereColumnmetode dapat melewati array beberapa kondisi. Kondisi ini akan bergabung menggunakan andoperator.

Contoh:

$users = DB::table('users')
            ->whereColumn([
                ['first_name', '=', 'last_name'],
                ['updated_at', '>', 'created_at']
            ])->get();

$users = User::whereColumn([
                ['first_name', '=', 'last_name'],
                ['updated_at', '>', 'created_at']
            ])->get();

Untuk informasi lebih lanjut, lihat bagian dokumentasi ini https://laravel.com/docs/5.4/queries#where-clauses


8
Model::where('column_1','=','value_1')->where('column_2 ','=','value_2')->get();

ATAU

// If you are looking for equal value then no need to add =
Model::where('column_1','value_1')->where('column_2','value_2')->get();

ATAU

Model::where(['column_1' => 'value_1','column_2' => 'value_2'])->get();

5

Pastikan untuk menerapkan filter lain ke sub kueri, jika tidak, atau mungkin mengumpulkan semua catatan.

$query = Activity::whereNotNull('id');
$count = 0;
foreach ($this->Reporter()->get() as $service) {
        $condition = ($count == 0) ? "where" : "orWhere";
        $query->$condition(function ($query) use ($service) {
            $query->where('branch_id', '=', $service->branch_id)
                  ->where('activity_type_id', '=', $service->activity_type_id)
                  ->whereBetween('activity_date_time', [$this->start_date, $this->end_date]);
        });
    $count++;
}
return $query->get();

Terima kasih telah menambahkan 'use ($ service)'. Jawaban Juljan hampir seperti yang saya butuhkan. Komentar Anda membantu saya meneruskan string pencarian saya ke kueri.
Elliot Robert

5
$projects = DB::table('projects')->where([['title','like','%'.$input.'%'],
    ['status','<>','Pending'],
    ['status','<>','Not Available']])
->orwhere([['owner', 'like', '%'.$input.'%'],
    ['status','<>','Pending'],
    ['status','<>','Not Available']])->get();

3

Tanpa contoh nyata, sulit untuk membuat rekomendasi. Namun, saya tidak pernah perlu menggunakan klausa WHERE sebanyak itu dalam kueri dan itu mungkin mengindikasikan masalah dengan struktur data Anda.

Mungkin bermanfaat bagi Anda untuk belajar tentang normalisasi data: http://en.wikipedia.org/wiki/Third_normal_form


3

Anda dapat menggunakan fasih di Laravel 5.3

Semua hasil

UserModel::where('id_user', $id_user)
                ->where('estado', 1)
                ->get();

Hasil parsial

UserModel::where('id_user', $id_user)
                    ->where('estado', 1)
                    ->pluck('id_rol');

3
Bagaimana ini berbeda dari pertanyaan?
veksen

2

gunakan whereInkondisi dan lulus array

$array = [1008,1009,1010];

User::whereIn('users.id', $array)->get();


1

Anda dapat menggunakan array di mana klausa seperti yang ditunjukkan di bawah ini.

$result=DB::table('users')->where(array(
'column1' => value1,
'column2' => value2,
'column3' => value3))
->get();

1
DB::table('users')
            ->where('name', '=', 'John')
            ->orWhere(function ($query) {
                $query->where('votes', '>', 100)
                      ->where('title', '<>', 'Admin');
            })
            ->get();

1

Sesuai saran saya jika Anda melakukan filter atau pencarian

maka Anda harus pergi dengan:

        $results = User::query();
        $results->when($request->that, function ($q) use ($request) {
            $q->where('that', $request->that);
        });
        $results->when($request->this, function ($q) use ($request) {
            $q->where('this', $request->that);
        });
        $results->when($request->this_too, function ($q) use ($request) {
            $q->where('this_too', $request->that);
        });
        $results->get();

apakah pencarian terjadi di sisi phpside atau sql?
Tn. Mohamed

Sisi sql. Sql query dieksekusi sebagai parameter permintaan. ex. jika requrst memiliki param ini. Lalu di mana ini = '' di mana kondisi ditambahkan ke kueri.
Dhruv Raval

1

Gunakan ini

$users = DB::table('users')
                    ->where('votes', '>', 100)
                    ->orWhere('name', 'John')
                    ->get();

0

Menggunakan Eloquent murni, terapkan seperti itu. Kode ini mengembalikan semua pengguna yang login yang akunnya aktif. $users = \App\User::where('status', 'active')->where('logged_in', true)->get();


0

Contoh kode.

Pertama :

$matchesLcl=[];

array terisi di sini menggunakan hitungan / loop kondisi yang diinginkan , secara bertahap:

if (trim($request->pos) != '') $matchesLcl['pos']= $request->pos;

dan di sini:

if (trim($operation) !== '')$matchesLcl['operation']= $operation;

dan selanjutnya dengan fasih seperti:

if (!empty($matchesLcl))
    $setLcl= MyModel::select(['a', 'b', 'c', 'd'])
        ->where($matchesLcl)
        ->whereBetween('updated_at', array($newStartDate . ' 00:00:00', $newEndDate . ' 23:59:59'));
else 
    $setLcl= MyModel::select(['a', 'b', 'c', 'd'])
        ->whereBetween('updated_at', array($newStartDate . ' 00:00:00', $newEndDate . ' 23:59:59'));

-4
public function search()
{
    if (isset($_GET) && !empty($_GET))
    {
        $prepareQuery = '';
        foreach ($_GET as $key => $data)
        {
            if ($data)
            {
                $prepareQuery.=$key . ' = "' . $data . '" OR ';
            }
        }
        $query = substr($prepareQuery, 0, -3);
        if ($query)
            $model = Businesses::whereRaw($query)->get();
        else
            $model = Businesses::get();

        return view('pages.search', compact('model', 'model'));
    }
}

Ini sangat rentan terhadap injeksi SQL.
rrrhys

-21
$variable = array('this' => 1,
                    'that' => 1
                    'that' => 1,
                    'this_too' => 1,
                    'that_too' => 1,
                    'this_as_well' => 1,
                    'that_as_well' => 1,
                    'this_one_too' => 1,
                    'that_one_too' => 1,
                    'this_one_as_well' => 1,
                    'that_one_as_well' => 1);

foreach ($variable as $key => $value) {
    User::where($key, '=', $value);
}

Ini akan mengeksekusi beberapa query.
veksen
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.