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?

veksen
sumber
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 ...)
Jarek Tkaczyk
sumber
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();
Luis Dalmolin
sumber
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();
Juljan
sumber
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')
alexglue
sumber
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)
srmilon
sumber
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();
Majbah Habib
sumber
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

Alex Quintero
sumber
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();
DsRaj
sumber
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();
adamk
sumber
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();
Lim Kean Phang
sumber
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

Aaron Cicali
sumber
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');
Cristhian Carreño
sumber
3
Bagaimana ini berbeda dari pertanyaan?
veksen
2

gunakan whereInkondisi dan lulus array

$array = [1008,1009,1010];

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

Rahul Tathod
sumber
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();
Abhijeet Navgire
sumber
1
DB::table('users')
            ->where('name', '=', 'John')
            ->orWhere(function ($query) {
                $query->where('votes', '>', 100)
                      ->where('title', '<>', 'Admin');
            })
            ->get();
pardeep
sumber
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();
Dhruv Raval
sumber
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();
Sooraj Thekkepatt
sumber
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();

Craig GeRa
sumber
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'));
CodeToLife
sumber
-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'));
    }
}
Muhammad Arslan
sumber
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);
}
Yuri Lazo
sumber
Ini akan mengeksekusi beberapa query.
veksen