Laravel join with LIKE CONCAT - php

Laravel 5.1.11
I have a simple search in my shop:
public function search($request $request)
{
return Catalog::where('title', 'like', '%'.$request->searchQuery.'%')
->orderBy('id', 'desc')
->paginate(50);
}
This is worked!
But people are looking for goods so: Pump BOSCH. And search result is null.
Because I changed my select:
public function search($request $request)
{
$searchQ = preg_split('/\s+/', $request->searchQuery, -1, PREG_SPLIT_NO_EMPTY);
return Catalog::where(function ($q) use ($searchQ) {
foreach ($searchQ as $value) {
$q->orWhere('title', 'like', "%{$value}%");
}
})
->orderBy('id', 'desc')
->paginate(50);
}
And this is worked), and show all Pumps!
But i want show only one Pump bosch.
My DB table manufactories:
| id | title |
| :--: | :----- |
| 1 | AlKO |
| 2 | BOSCH |
AND catalogs, where m_id is id from table manufactory:
| id | m_id | title | url |
| :--: | :---: | :---- | :--------- |
| 1 | 1 | pump | pump-alko |
| 2 | 2 | pump | pump-bosch |
How do I change the MySQL search query (adding LEFT JOIN and CONCAT) to find Pump bosch?
To make it look like this: CONCAT('catalogs.title', ' ', 'manufactories.title') LIKE '%'.$request->searchQuery.'%'

You can do simply like this,
$data = DB::table('manufactories')
->join('catalogs','manufactories.id','=','catalogs.m_id')
->select('manufactories.title','catalogs.title')
->where(DB::raw('CONCAT(manufactories.title," ",catalogs.title)'), 'like',"%{$value}%")
->get();
I hope it helps,

You can use the Query Builder to do joins e.g.
DB::table('catalogs')
->select('catalogs.*')
->join('manufactories', 'catalogs.m_id', '=', 'manufactories.id', 'left')
->where(function($q) use ($searchQ) {
foreach ($searchQ as $value) {
$q->orWhere('manufactories.title', 'like', "%{$value}%");
$q->orWhere('catalogs.title', 'like', "%{$value}%");
}
})
->get();

Related

Search query function on Laravel

I have an album that has images. I'm having a problem with doing the search function. I want to search for photos with the following caption. Here's what I did so far.
Albums table:
| id | album_name | sort |
|----|------------|------|
| 1 | album_1 | 3 |
| 2 | album_2 | 2 |
| 3 | album_3 | 1 |
Photos table:
| id | album_id | name | sort |
|----|----------|-------|------|
| 1 | 1 | name1 | 1 |
| 2 | 1 | name2 | 2 |
| 3 | 2 | name3 | 3 |
and the following relations on my models:
Photo.php
public function album()
{
return $this->belongsTo(Album::class);
}
Album.php
public function images()
{
return $this->hasMany(Photo::class, 'album_id', 'id)->orderBy('sort');
}
GalleryController.php
public function index(Request $request)
{
$photos = Album::has('images')->orderBy('sort')->with('images')->get();
}
if (!empty($request->search)) {
$photos = Album::whereHas('images', function($query) use ($request) {
$query->where('name', 'like', '%' . $request->search . '%');
})->with('images')->get();
The search function works but if I search for a specific image within the album it returns all of the images in that album.
It's not very pretty, but this is basically what you want.
I've commented the code to explain it.
if (!empty($request->search)) {
$queryString = '%' . $request->search . '%';
$queryClosure = function ($query) use ($queryString) {
$query->where('name', 'LIKE', $queryString);
};
// Get only albums that have images that match the query string.
// This will filter the albums, not the images.
$photos = Album::whereHas('images', $queryClosure)
// Now filter the images of those albums.
->with(['images' => $queryClosure])
// Return the collection.
->get();
}
Edit:
I have updated the answer to use Tim Lewis's suggestion from the comments.
Since the closure is repeated for both steps, we can store it in a variable to keep the code DRY.

where column = NULL and whereNotIn not working together in laravel

My code not working together, but if i only use one of them->where('numbers.client_group_id', NULL) OR ->whereNotIn('id', function($query) use ($request){ itu work normal.
$model = DB::table('numbers')->select('id','phone');
$model
->where('numbers.client_group_id', NULL)
->whereNotIn('id', function($query) use ($request){
$query->select('number_push_logs.number_id')->from('number_push_logs')->where('number_push_logs.client_group_id',$request->client_group);
})
->orderBy('quality', 'asc')->limit($request->total_push);
this my table looks like:
numbers table
| id| phone | client_group_id|
|---|------------|----------------|
| 1 |0852176255**| 1 |
| 2 |0852176255**| 1 |
| 3 |0852176255**| NULL |
number_push_logs table
| id| number_id |client_group_id |
|---|------------|----------------|
| 1 |1 | 1 |
| 2 |1 | 2 |
| 3 |2 | 2 |
so i want to select numbers data where client_group_id = NULL and id numbers not in number_push_log table with specific client_group_id
Try something like this. Use join. It performs better than nested demand.
\DB::table('numbers as n')
->select('id','phone')
->leftJoin('number_push_logs as npl', 'n.client_group_id', '=', 'npl.client_group_id')
->whereNull('npl.id')
->orderBy('quality', 'asc')
->limit($request->total_push);

How to use CASE WHEN in Eloquent ORM?

How to use CASE WHEN in Eloquent ORM?
I'm wondering if it will work if add
$query->selectRaw('CASE WHEN (created_at = '.$daterange.') THEN 'P' as attendance) something like that, but i don't know how to use CASE WHEN is it possible?
// Create a loop for date range
$daterange = [];
for ($day = $search_from; $day <= $search_to; $day++) {
$daterange[]['date'] = $this->carbon->parse($day)->format('M d');
}
// Search Student
$students = User::has('userStudentAttendance')->with(['userStudentAttendance' => function($query) use ($details,$search_from, $search_to){
$query->where('status', $details);
$query->where(function($query) use ($search_from, $search_to){
$query->whereBetween(DB::raw('Date(created_at)'), [$search_from, $search_to]);
});
$query->groupby('user_id')->groupby(DB::raw('Date(created_at)'));
}])
->leftjoin('sys_user_student', 'sys_user_student.user_id', '=', 'sys_user.user_id')
->leftjoin('sys_mf_section', 'sys_mf_section.section_id', '=', 'sys_user_student.section_id')
->leftjoin('sys_mf_grade', 'sys_mf_grade.grade_id', '=', 'sys_mf_section.grade_id')
->where('user_type_id', '4')
->where('sys_mf_section.section_id', $request->getParam('section_id'))
->where('sys_mf_grade.grade_id', $request->getParam('grade_id'))
->orderBy('sys_user.last_name')
->get();
This is the look of the report that i want to achieve:
+--------------------------------------------------+
|student ID|full Name|Oct 23|Oct 24|Oct 25 | Oct 26|
|1 |stud 1 | P | P | P | A |
|2 |stud 2 | P | A | P | P |
|3 |stud 3 | P | P | P | P |
|4 |stud 4 | P | P | P | A |
|5 |stud 5 | A | A | A | A |
+--------------------------------------------------+
I guess you are using Laravel. Maybe you could use select raw query provided by Laravel.
->select('users.id AS user_id', 'users.name',
DB::raw('(CASE WHEN users.status = 0
THEN "active" WHEN users.status = 1
THEN "not active"
ELSE "pending" END) AS
status_user'))
->orderBy('shares.created_at', 'desc')

Eloquent query where column is in another table

I have two tables, posts and likes. I need to create a query, using Eloquent, that gets all posts that have been liked by a specific user_id.
In other words, it should be something like this:
SELECT * FROM posts p LEFT JOIN likes l ON p.id = l.post_id WHERE l.user_id = 2 ORDER BY l.created_at DESC
posts table:
+----+---------+------------+-------------+
| id | user_id | message | created_at |
+----+---------+------------+-------------+
| 1 | 2 | Hello! | <SOME TIME> |
| 2 | 3 | World! | <SOME TIME> |
| 3 | 2 | Something. | <SOME TIME> |
| 4 | 2 | Another. | <SOME TIME> |
+----+---------+------------+-------------+
likes table:
+----+---------+---------+-------------+
| id | post_id | user_id | created_at |
+----+---------+---------+-------------+
| 1 | 1 | 2 | <SOME TIME> |
| 2 | 2 | 2 | <SOME TIME> |
| 3 | 1 | 3 | <SOME TIME> |
| 4 | 3 | 2 | <SOME TIME> |
+----+---------+---------+-------------+
Here is my Postclass:
<?php
class Post extends Eloquent {
protected $table = 'posts';
public function likes()
{
return $this->hasMany('Like');
}
}
And the Like class:
<?php
class Like extends Eloquent {
protected $table = 'likes';
public function post()
{
return $this->belongsTo('Post');
}
}
How can I do this?
This should work:
$userId = //however you get the userid here.
$posts = Post::whereHas('likes', function ($q) use ($userId) {
$q->where('user_id', $user_id);
})->get();
You can use Laravel's DB class to perform joins on two or more tables, following is how your query will be executed in laravel:
$users = DB::table('posts')
->leftJoin('likes', 'posts.id', '=', 'likes.post_id')
->select('posts.*', 'likes.*')
->where('likes.user_id', '=', '2')
->orderBy('likes.created_at', 'desc')
->get();
Don't forget to use DB class on the top of your controller;
If you want to do it with eloquent, you should do the follwing:
$result = Post::whereHas('likes', function ($q) use($user_id)
{
$q->where('user_id', $user_id);
})
->orderBy('likes.created_at')
->get();

Laravel 'whereNotIn' query difficulty

I'm trying to run the following queries and running into this error:
preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
When I remove the 'whereNotIn' part the query works. I know for a fact that the first query works, as I tested that individually. How can I fix this error? Here's the code:
$alreadyCheckedOutDevicesQuery = DB::connection('NEWSTAFFPORTAL')->table('DeviceCheckout_checkout')->select('deviceID')->where('inBy', '=', '')->get();
$alreadyCheckedOutDevices = GlobalModel::convertDBObjectsToArray($alreadyCheckedOutDevicesQuery);
$deviceTableInformation = DB::connection('NEWSTAFFPORTAL')->table('DeviceCheckout_deviceListTestingTable')->select('deviceID', 'name', 'type', 'brand', 'model')->whereNotIn('deviceID', $alreadyCheckedOutDevices)->orderBy('name', 'ASC')->get();
Try doing it in a subquery:
$info = DB::connection('NEWSTAFFPORTAL')
->table('DeviceCheckout_deviceListTestingTable')
->select('deviceID', 'name', 'type', 'brand', 'model')
->orderBy('name', 'asc')
->whereNotIn('deviceID', function ($query)
{
$query->from('DeviceCheckout_checkout')
->select('deviceID')
->where('inBy', '');
})
->get();
This will work:
$alreadyCheckedOutDevices = DB::connection('NEWSTAFFPORTAL')
->table('DeviceCheckout_checkout')
->where('inBy', '=', '')
->lists('deviceID');
$deviceTableInformation = DB::connection('NEWSTAFFPORTAL')
->table('DeviceCheckout_deviceListTestingTable')
->select('deviceID', 'name', 'type', 'brand', 'model')
->whereNotIn('deviceID', $alreadyCheckedOutDevices)
->orderBy('name', 'ASC')
->get();
Also it should be better in terms of performance, than using subquery.
Simplified explain:
+----+--------------------+-----------------+---------+------+-------------+
| id | select_type | type | key | rows | Extra |
+----+--------------------+-----------------+---------+------+-------------+
| 1 | PRIMARY | ALL | NULL | 100 | Using where |
| 2 | DEPENDENT SUBQUERY | unique_subquery | PRIMARY | 1 | Using index |
+----+--------------------+-----------------+---------+------+-------------+
+----+-------------+------+------+------+-------------+
| id | select_type | type | key | rows | Extra |
+----+-------------+------+------+------+-------------+
| 1 | SIMPLE | ALL | NULL | 100 | Using where |
+----+-------------+------+------+------+-------------+

Categories