LARAVEL column Eloquent query with OrderByRaw - laravel

I need to calculate distance with latitude,longitude and order it by nearest,
but in my OrderBy clause latitude is missing, I don't know why
->with(['foglio' => function ($query) use ($latitude, $longitude) {
$query->select([
'id',
'indirizzo',
'piano',
'categoria',
'consistenza',
'latitude',
'longitude',
]);
$query->WhereNotNull(['indirizzo', 'latitude', 'longitude']);
}])
->limit($limit)
->orderBy(DB::raw('ABS(latitude - ' . $latitude . ') + ABS(longitude - ' . $longitude . ')'), 'ASC')
->get();

You could use:
->orderByRaw('ABS(latitude - ' . $latitude . ') + ABS(longitude - ' . $longitude . ') ASC')

You should use left join, not eager loading.
Eager loading will produce two seperate queries and that's why you can't access latitude
column in order by clause.

Related

How can I escase string in whereRaw?

In laravel 9 I use whereRaw in code like :
$query->whereRaw( 'item.day ' . $sign . "'".$filter_day."' " );
But I need to escape it.
Function mysql_real_escape_string is absolute now...
What can I use here ? I work with mysql8 now, but I prefer decision for different db on laravel side.
Thanks in advance!
I suggest reading the Laravel documentation thoroughly: https://laravel.com/docs/9.x/queries#raw-methods
You can escape the string using ? as the link I given above.
$query->whereRaw( 'item.day ' . $sign . ' ?', [$filter_day]);
You must NOT escape the operator $sign because its an MYSQL operator.
And also you must make sure that you properly check/sanitize $sign to avoid SQL injection. E.g.
if (in_array($sign, ['=', '<', '>', '<=', '>=', '!=', '<>'])) {
$query->whereRaw( 'item.day ' . $sign . ' ?', [$filter_day]);
}

Laravel push in order

Hi I am trying to combine two collections in a way that, the difference from the second collection is inserted one by one at the end of the first collection. However, when I try to use diff to find the difference between two collections and push each different set, the order seems to be messed up. Can someone help me with this please?
$serviceids = Service::where('service_name', 'like', '% ' . $chip_service . ' %')
->orWhere('service_name', 'like', '% ' . $chip_service)
->orWhere('service_name', 'like', $chip_service . ' %')
->orWhere('service_name', $chip_service)
->pluck('service_recordid');
$service_description_all = Service::where('service_description', 'like', '% ' . $chip_service . ' %')
->orWhere('service_description', 'like', '% ' . $chip_service)
->orWhere('service_description', 'like', $chip_service . ' %')
->orWhere('service_description', $chip_service)
->pluck('service_recordid');
$service_description = $service_description_all->diff($serviceids)->all();
foreach ($service_description as $key => $ser){
$serviceids->push($ser);
}
push function acts like stack, so the first element will be at the end the last in the stack.
you can use directly:
$serviceids = $service_description + $serviceids

Convert raw SQL query to Eloquent

I need your help, guys. I have this query:
SELECT * FROM users
where lcase(concat(firstname, ' ', lastname)) like lcase(concat('%', replace('%searchterm%', ' ', '%'), '%'))
OR lcase(concat(lastname, ' ', firstname)) like lcase(concat('%', replace('%searchterm%', ' ', '%'), '%'))
OR lcase(location) like lcase('%searchterm%')
Is it possible to use a nice eloquent query instead of DB::select(DB::raw()) to use pagination?
You could use whereRaw and orWhereRaw methods on a Eloquent Builder to use raw expressions while maintaining the ability to get model instances as a result.
The advantages is that you can still use PDO parameter binding and therefore avoid SQL Injections though $searchTerm.
You can also find out more about raw expressions in the documentation;
// Assuming $searchTerm contains the term that you need to search the database for
$users = User::whereRaw('lcase(concat(firstname, " ", lastname)) like lcase(concat("%", replace("%?%", " ", "%"), "%"))', [ $searchTerm ])
->orWhereRaw('lcase(concat(lastname, " ", firstname)) like lcase(concat("%", replace("%?%", " ", "%"), "%"))', [ $searchTerm ])
->orWhereRaw('lcase(location) like lcase("%?%")', [ $searchTerm ])
->get();
To split your where condition you can use orWhere method.
User::
->where(DB::raw('condition_one'))
->orWhere(DB::raw('condition_two'))
->orWhere(DB::raw('condition_three'))
->paginate();

Laravel Eloquent Where Query with multiple words

I have the following query (cut for brevity):
$employees = Employee::where('first_name', 'LIKE', "%$query%")
->orWhere('last_name', 'LIKE', "%$query%")
Now this works when the user inputs a single name like 'John' or 'Smith', but when they input 'John Smith' it doesn't find anything. Am I missing an extra orWhere?
Try this :
Employee::where(DB::raw('CONCAT(first_name," ",lastname)'), 'LIKE', "%' . $query . '%"))
You would have to add a 3rd orWhere. For our search function we use something like this:
Employee::whereraw("COALESCE(last_name, '') LIKE '%$query%'")
->Orwhereraw("COALESCE(first_name, '') LIKE '%$query%'")
->Orwhereraw("COALESCE(last_name + ', ' + first_name, '') LIKE '%$query%'")
Adding Coalesce seemed to help with some issues we had when we first implemented it, not sure if it is necessary in your case though.
You can do :
$fullName = trim($query);
$employees = Employee::where(DB::raw("CONCAT(first_name, ' ', last_name)"), 'LIKE', "%".$fullName."%")->get();
You are concatenating the values in database for first_name + ' ' + last_name and then using like to find the matching records.

Group By and Order By in laravel 5.4

I just need to order my records according to updated, and then group them according to card_id.
This is my code:
$triages = Triyage::latest('updated_at')->groupBy('card_id')->paginate(8);
return view('Admin.Opd.card_opd', compact('triages'));
Use a subquery JOIN:
$join = Triyage::select('card_id', DB::raw('max(updated_at) updated_at'))
->groupBy('card_id');
$sql = '(' . $join->toSql() . ') as latest';
$triages = Triyage::join(DB::raw($sql), function($join) {
$join->on('triyages.card_id', 'latest.card_id')
->on('triyages.updated_at', 'latest.updated_at');
})->paginate(8);

Resources