Replace Like in SQL for ENUM - php

Currently I am having success with the following query:
if (isset($data->action_needed_status) && $data->action_needed_status != '') {
$query->where('status', 'like', '%'.$data->action_needed_status.'%');
$query_count->where('status', 'like', '%'.$data->action_needed_status.'%');
The complaint was this:
Since status is an ENUM field you know that any valid status value
passed should match exactly. There shouldn't be a need for using LIKE
in the where statements.
What would be the best way to have same result without using LIKE?

Related

Get NULL/empty columns in Laravel eloquent query

Currently I'm working on a ajax search filters on Laravel, but I cannot get the correct info, this is the scenario:
I have 2 tables:
Table1: SoftwareRequest
Table2: DenyCategory
with a select option I get the name as Value
and I added that select option like in top of the query on the controller function:
$deniedReason = $request->get('deniedReason');
if($deniedReason == "All"){
$deniedReason = "";
}
So that means that every time I select "All" it will be empty so I can get all data like empty (this is the problem).
This is my current query:
$request_data = SoftwareRequest::leftJoin('DenyCategory', 'SoftwareRequest.DenyCategoryId', '=', 'DenyCategory.Id')->where('DenyCategory.Name', 'like', '%' . $deniedReason . '%')->paginate(20);
So the thing is that if I select another option rather than "All", for example "Already Available", I do get the excepted data, meaning all objects from table 1 joined with table 2 that has that option, but the problem comes when I select "All" it doesn't bring all the data it should and that's because not all objects have DenyCategoryId in Table1 meaning that some of those are Null/empty so it only brings the ones 'LIKE' Null/empty as I specified on the previous code block.
$deniedReason = $request->get('deniedReason');
if($deniedReason == "All"){
$deniedReason = "";
}
How can I get all data empty or not empty when I select the option All and as well as to get the data when I select another option? I bet it would have something to do with the query not being 'Like' but that's out of my knowledge scope.
Why not make the where clause optional?
$queryBuilder = SoftwareRequest::leftJoin('DenyCategory', 'SoftwareRequest.DenyCategoryId', '=', 'DenyCategory.Id')
// Only apply where-clause when denied reason has been provided.
if ($request->get('deniedReason') !== 'All') {
$queryBuilder = $queryBuilder->where('DenyCategory.Name', 'like', '%' . $deniedReason . '%');
}
$request_data = $queryBuilder->paginate(20);
I think you can improve your code a bit better but I'll leave that up to you with some pointers:
Eloquent relationships
Class Constants

Conditionally add where clause to eloquent query

I have a products database. I allow users to enter a search term and I display products related to their search term. I'm wanting to add the ability for the user to further filter these results by "gender" using AJAX. If the user selects a gender from a select box this is sent to the URL query string.
here is my code responsible for detecting if "gender" is in the query string.
$searchTerm = request('s');
$gender = request('gender');
$productsQuery = DB::table('products')
->where('title', 'LIKE', "%$searchTerm%");
if ($gender != "") {
$productsQuery->where('gender', '=', "%$gender%");
}
$productsQuery->get();
When this method is called. I receive an empty collection.
Your idea and approach is correct, but you are mixing LIKE and = queries. % is a wildcard, but that can be only be used with LIKE.
So, if you want to use a wildcard and LIKE,
if(!empty($gender)) {
$productsQuery->where('gender', 'LIKE', "%$gender%");
}
Or if you want to match by exact text,
if(!empty($gender)) {
$productsQuery->where('gender', $gender);
}
Your current code will search for the exact match of the literal string %male%, for example.
Keep in mind that by using a wildcard, male will also match female (as they both contain the word "male").
Actually you can do this in one query. Just like that:
$productsQuery = DB::table('products')
->where('title', 'LIKE', '%'.$searchTerm.'%')
->where(function($query) use ($gender){
if($gender != ""){
$query->where('gender', '=', $gender);
}
})
->get();
You should use LIKE also in the second where clause:
$productsQuery->where('gender', 'LIKE', "%{$gender%}");
EDITED
If you need to search for the exact gender you must not use wildcards at all.
$productsQuery->where('gender', '=', $gender);

Laravel Eloquent using where pattern

I have this PostgreSQL query which checks a value if it matches one of the string pattern in the table:
SELECT * FROM table WHERE 'value' LIKE column
I want to do this in Laravel 5.1 using Eloquent. But doing something like :
$prefix = 'value';
Model::where($prefix, 'LIKE', column)->firstOrFail();
returns an error. Apparently the first argument of where ($prefix) will always be treated as column name in Laravel (put between double quotes). Is there anyway to fix this or any better way to do it?
Use raw:
Model::whereRaw("'{$prefix}' LIKE column")->firstOrFail();
Replace:
Model::where($prefix, 'LIKE', "'%' || column_name || '%'")->firstOrFail();
With:
Model::where('.$prefix.', 'LIKE', "'%' || column_name || '%'")->firstOrFail();

Laravel: where condition based on db field

How to make a whereclause that is based on an existing field in the database, and not on an input parameter?
$query = DB::table('events')
->join('events_dates', function($join) use ($data){
$join->on('events.id', '=', 'events_dates.event_id');
$join->where('events_dates.start_date', "<=", $data['date_end']);
$join->where('events_dates.end_date', '>=', $data['date_start']);
});
This works well because the where clause is based on an input parameter.
What I need is a Where clause that is based on a field that is already in the database:
Something like this:
$query = DB::table('events')
->join('events_dates', function($join) use ($data){
$join->on('events.id', '=', 'events_dates.event_id');
//If db field of record: recurrent == 0 then
$join->where('events_dates.start_date', "<=", $data['date_end']);
$join->where('events_dates.end_date', '>=', $data['date_start']);
/* If db field of record: "recurrent" == "1" then
$join->where //another query
*/
});
Is this achievable with the laravel ORM, or should I write a native SQL query?
Haven't found a suitable answer in the docs or in existing posts.
You need to use...
where('column1', '=', DB::raw('column2'));
...to use the field value instead of the string "column2".
In this answer I further explained why.

How to assemble a query with various optional parameters in Laravel?

I have a research to do in a database. Not always I'll be using all of parameters. The user may want to research for a name, but not address or the other way around.
I've tried to use advanced wheres and even unions, but none seems to work. All of them give me a SQL error "General error: 1221 Incorrect usage of UNION and ORDER BY".
Here's a piece of code I've tried
$city_name = ($city_name != null) ? DB::table('cities')->where('name', 'LIKE', "%$city_name%") : DB::table('cities');
$state = ($state_id != '--') ? DB::table('cities')->where('state_id', '=', $state_id) : DB::table('cities');
$cities = DB::table('cities')->union($city_name)->union($state)->orderBy('name')->get();
But it gives me the above described error.
What I really want to do is to select, dinamically, what parameters I put in the query and even assemble it "on the fly". Does anyone knows how to do that?
If I couldn't make myself clear, please let me know in the comments...
I think you need somethink like this:
$query = DB::table('cities');
if ($city_name != null)
{
$query->where('name', 'LIKE', "%$city_name%");
}
if ($state_id != '--')
{
$query->where('state_id', '=', $state_id);
}
$cities = $query->orderBy('name')->get();

Categories