简体   繁体   中英

Laravel SQL Query whereIn + where + orWhere

I'm having some trouble with this query and I'm out of ideas, let me explain:

Here is what I have:

  • Table of users (Columns that matter for this question: name, description)
  • Table of services (Columns that matter for this question: name, description, subcategory_id, category_id)
  • Pivot table for the user-services relationship

Here is what I want to happen:

  • The app must be able to search by text in the name/description of the user and his related services.
  • Also the app can send me one category_id and multiple subcategory_ids for the search, so the related services must have that id

First search works alright, problem comes when I try the second one. Is like it doesn't take into account every parameter of the query. I want it to search by text ONLY if that category_id or subcategory_id matches, but it shows results without having that match.

Here is what I've got so far:

        $professionals = \DB::table('users')->where('role_id', Role::PROFESSIONAL_USER)
                            ->join('professional_service', 'users.id', '=', 'professional_service.user_id', 'left')
                            ->join('services', 'services.id', '=', 'professional_service.service_id', 'left')
                            ->select('users.id', 'users.name as name', 'users.last_name as last_name', 'users.gender as gender', 'users.description as description', 'users.city', 'users.latitude', 'users.longitude', 'users.wpicture')
                            ->where('users.name', 'like', '%'.$request->search.'%')
                            ->where('services.category_id', '=', $request->category_id)
                            ->orWhere('users.description', 'like', '%'.$request->search.'%')
                            ->orWhere('services.name', 'like', '%'.$request->search.'%')
                            ->orWhere('services.description', 'like', '%'.$request->search.'%')
                            ->whereIn('services.subcategory_id', $request->subcategories)
                            ->groupBy('users.id')
                            ->paginate($request->per_page);

Any help would be appreciated. Thanks!

Edited (using closure as suggested in comments):

        $professionals = \DB::table('users')->where('role_id', Role::PROFESSIONAL_USER)
                            ->join('professional_service', 'users.id', '=', 'professional_service.user_id', 'left')
                            ->join('services', 'services.id', '=', 'professional_service.service_id', 'left')
                            ->select('users.id', 'users.name as name', 'users.last_name as last_name', 'users.gender as gender', 'users.description as description', 'users.city', 'users.latitude', 'users.longitude')
                            ->where(function($query) use ($search){ $query->where('users.name', 'like', '%'.$search.'%'); $query->orWhere('users.description', 'like', '%'.$search.'%'); $query->orWhere('services.name', 'like', '%'.$search.'%'); $query->orWhere('services.description', 'like', '%'.$search.'%');})
                            ->where('services.category_id', '=', $request->category)
                            ->whereIn('services.subcategory_id', explode(',', $request->subcategories))
                            ->groupBy('users.id')
                            ->paginate($request->per_page);

Problem now is, if the user only search by text and category / subcategories are null, no results are shown. How can I ignore them if they are null?

Found the solution (I'm sure it can be done in a better way, but this is working for me):

        $professionals = \DB::table('users')->where('role_id', Role::PROFESSIONAL_USER)
                            ->join('professional_service', 'users.id', '=', 'professional_service.user_id', 'left')
                            ->join('services', 'services.id', '=', 'professional_service.service_id', 'left')
                            ->select('users.id', 'users.name as name', 'users.last_name as last_name', 'users.gender as gender', 'users.description as description', 'users.city', 'users.latitude', 'users.longitude')
                            ->where(function($query) use ($search){ $query->where('users.name', 'like', '%'.$search.'%'); $query->orWhere('users.description', 'like', '%'.$search.'%'); $query->orWhere('services.name', 'like', '%'.$search.'%'); $query->orWhere('services.description', 'like', '%'.$search.'%');})
                            ->when($category, function($query) use ($category) { $query->where('services.category_id', '=', $category);})
                            ->when($subcategories, function($query) use ($subcategories) { $query->whereIn('services.subcategory_id', $subcategories);})
                            ->groupBy('users.id')
                            ->paginate($request->per_page);

Thanks for the tip about closures.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM