Làm thế nào để tạo nhiều truy vấn mệnh đề bằng cách sử dụng Laravel Eloquent?


406

Tôi đang sử dụng trình xây dựng truy vấn Laravel Eloquent và tôi có một truy vấn trong đó tôi muốn có một WHEREmệnh đề trên nhiều điều kiện. Nó hoạt động, nhưng nó không thanh lịch.

Thí dụ:

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

Có cách nào tốt hơn để làm điều này, hay tôi nên gắn bó với phương pháp này?


4
Có nhiều khả năng về cách làm thế nào điều này có thể được đơn giản hóa, nhưng điều đó sẽ đòi hỏi một số mã thực tế hơn. Bạn có thể cập nhật mã để thực tế hơn một chút? Ví dụ, có những lúc nhiều ->where(...)cuộc gọi có thể được thay thế bằng một ->whereIn(...)cuộc gọi, et cetera .
jonathanmarvens

2
Giải pháp của @Jarek Tkachot nên là câu trả lời, tôi đồng ý. Nhưng tôi thích mã của bạn như tập lệnh xây dựng để hiểu và bảo trì.
Tiefan Ju

Câu trả lời:


620

Trong Laravel 5.3 (và vẫn đúng với 7.x ), bạn có thể sử dụng các chi tiết nhỏ hơn được truyền dưới dạng một mảng:

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

Cá nhân tôi chưa tìm thấy trường hợp sử dụng cho việc này chỉ qua nhiều wherecuộc gọi, nhưng thực tế là bạn có thể sử dụng nó.

Kể từ tháng 6 năm 2014, bạn có thể chuyển một mảng tới where

Miễn là bạn muốn tất cả các toán tử wheressử dụng and, bạn có thể nhóm chúng theo cách này:

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

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

Sau đó:

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

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

Ở trên sẽ dẫn đến truy vấn như vậy:

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

8
Làm thế nào để bạn chỉ định các nhà điều hành?
Styphon

9
@Styphon Bạn không. Hiện tại nó chỉ hoạt động với =.
Jarek Tkachot

5
@Styphon và nếu tôi muốn thực hiện : WHERE (a IS NOT NULL AND b=1) OR (a IS NULL AND b=2);?
alexglue

9
Bạn cũng có thể vượt qua một loạt các điều kiện như thế này:$users = DB::table('users')->where([ ['status', '=', '1'], ['subscribed', '<>', '1'], ])->get();
số không và

3
@jarek: Làm thế nào để tôi bao gồm whereNotIncâu trả lời của bạn với việc có các đầu wheremối khác ?
Kalanka

93

Phạm vi truy vấn có thể giúp bạn để mã của bạn dễ đọc hơn.

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

Cập nhật câu trả lời này với một số ví dụ:

Trong mô hình của bạn, tạo các phương thức phạm vi như thế này:

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

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

Sau đó, bạn có thể gọi phạm vi này trong khi xây dựng truy vấn của mình:

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

cách thực hành tốt nhất cho một điều kiện như thế này là gì, truy vấn-> trong đó ('start_date'> $ startDate) vẫn ổn khi sử dụng Phạm vi?
Buwaneka Kalansuriya

72

Bạn có thể sử dụng các truy vấn con trong chức năng ẩn danh như thế này:

 $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

Trong trường hợp này, bạn có thể sử dụng một cái gì đó như thế này:

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

Nó sẽ cung cấp cho bạn một truy vấn như:

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

Điều kiện sử dụng Array:

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

Sẽ tạo truy vấn như dưới đây:

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

Điều kiện sử dụng chức năng Antonymous:

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

Sẽ tạo truy vấn như dưới đây:

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

12

Mệnh đề nhiều nơi

    $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);
    }

cuối cùng cũng nhận được kết quả

    $result = $query->get();

9

Các whereColumnphương pháp có thể được thông qua một loạt các điều kiện nhiều. Những điều kiện này sẽ được tham gia bằng cách sử dụng andtoán tử.

Thí dụ:

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

Để biết thêm thông tin, hãy kiểm tra phần này của tài liệu https://laravel.com/docs/5.4/queries#where-clauses


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

HOẶC LÀ

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

HOẶC LÀ

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

5

Hãy chắc chắn áp dụng bất kỳ bộ lọc nào khác cho các truy vấn phụ, nếu không, hoặc có thể thu thập tất cả các bản ghi.

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

Cảm ơn bạn đã thêm 'use ($ service)'. Câu trả lời của Juljan gần như là những gì tôi cần. Nhận xét của bạn đã giúp tôi chuyển chuỗi tìm kiếm của mình vào truy vấn.
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

Nếu không có một ví dụ thực tế, rất khó để đưa ra một khuyến nghị. Tuy nhiên, tôi chưa bao giờ cần sử dụng nhiều mệnh đề WHERE trong truy vấn và nó có thể chỉ ra vấn đề với cấu trúc dữ liệu của bạn.

Nó có thể hữu ích cho bạn để tìm hiểu về chuẩn hóa dữ liệu: http://en.wikipedia.org/wiki/Third_n normal_form


3

Bạn có thể sử dụng tài hùng biện trong Laravel 5.3

Tất cả kết quả

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

Kết quả một phần

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

3
Điều này khác với câu hỏi như thế nào?
veksen

2

sử dụng whereInđiều kiện và vượt qua mảng

$array = [1008,1009,1010];

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


1

Bạn có thể sử dụng mảng trong mệnh đề where như dưới đây.

$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

Theo đề nghị của tôi nếu bạn đang thực hiện lọc hoặc tìm kiếm

sau đó bạn nên đi với:

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

việc tìm kiếm xảy ra ở phía phpside hay sql?
Ông Mohamed

Bên Sql. Truy vấn Sql thực thi như tham số yêu cầu. Ví dụ. nếu requrst có thông số này. Sau đó, nơi này = '' nơi điều kiện được thêm vào truy vấn.
Dhruv Raval

1

Dùng cái này

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

0

Sử dụng Eloquent thuần túy, thực hiện nó như vậy. Mã này trả về tất cả người dùng đã đăng nhập có tài khoản đang hoạt động. $users = \App\User::where('status', 'active')->where('logged_in', true)->get();


0

Một mẫu mã.

Thứ nhất:

$matchesLcl=[];

mảng được điền vào đây bằng cách sử dụng số lượng / vòng lặp điều kiện mong muốn , tăng dần:

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

và đây:

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

và hơn nữa với các tài hùng biện như:

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'));
    }
}

Điều này rất dễ bị tổn thương khi tiêm 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);
}

Điều này sẽ thực hiện nhiều truy vấn.
veksen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.