I have multiple tables for generating a report.
I join all of tables in a query and finally I group them to get a unique shop ids.
My problem is I want to get the last record of image table but when I join it I always get the first image record.
when I use orderBy at the end of query, the joined records ordered and images records orders isn't changed.
How can I reverse image table before joining with shop table to get the last image record?
$result = DB::table('shops')
->leftjoin('addresses', 'addresses.model_id', '=', 'shops.id')
->leftjoin('users', 'users.id', '=', 'shops.user_id')
->leftjoin('states', 'addresses.state_id', '=', 'states.id')
->leftjoin('cities', 'addresses.city_id', '=', 'cities.id')
->leftjoin('images', 'shops.id', '=', 'images.imageable_id')
->leftjoin('reviews', 'shops.id', '=', 'reviews.shop_id')
->select(['shops.name as shopName', 'images.name as image',
])
->groupBy(['shops.id'])
->where('shops.user_id', $id)->get();
Related
Good day, I'm trying to get unique products with lowest prices.
I'm having a products table like this:
I would like to get a list of products with all columns. Now there are some products that have more than one supplier in that case I want to grab the product with the lowest cost_price.
So far I have tried this
$products = DB::table('products')
->select('identifier')
->selectRaw('MIN(cost_price) as cost_price')
->where('stock', '>', 0)
->groupBy('identifier')
->orderBy('cost_price', 'asc')
->distinct()->get();
This query returns me the correct results but I cant add more columns every time I add a column for example stock in select I need to add as well in GroupBy and then I'm just getting all products.
How to do it?
Thank you for reading.
You need greatest-n-per-group solution/approach for this problem.
The query;
SELECT products.*
FROM products
INNER JOIN (SELECT identifier, MIN(cost_price) AS minPrice
FROM products
WHERE stock > 0
GROUP BY identifier) AS sub
ON sub.minPrice = products.cost_price and sub.identifier = products.identifier;
The query builder version;
$sub = DB::table('products')
->where('stock', '>', DB::raw(0))
->groupBy('identifier')
->select('identifier', DB::raw('min(cost_price) as minPrice'));
return DB::table('products')
->join(DB::raw('(' . $sub->toSql() . ') as sub'), function ($join) {
$join->on('sub.minPrice', '=', 'products.cost_price');
$join->on('sub.identifier', '=', 'products.identifier');
})
->get(['products.*']);
I need all columns from invoice,invoice_details table but I want to get only one column (column name: amount) from my payment table. What will be my query for it? here is my controller.
$all_invoice = DB::table('invoice')
->join('invoice_details', 'invoice.invoice_id', '=', 'invoice_details.invoice_id')
->join('payment', 'invoice.invoice_id', '=', 'payment.invoice_id')
->where('invoice.client_id', 7)
->orderBy('invoice.invoice_id', 'DESC')
->get();
This very simple you need to add select clause in query like this.
$all_invoice = DB::table('invoice')->select(['invoice.*', 'payment.amount'])
->join('invoice_details','invoice.invoice_id','=','invoice_details.invoice_id')
->join('payment','invoice.invoice_id','=','payment.invoice_id')->where('invoice.client_id',7)->orderBy('invoice.invoice_id','DESC')->get();
If have still query the see the laravel docs in select option in query.
Just using select
$all_invoice = DB::table('invoice')
->join('invoice_details', 'invoice.invoice_id','=','invoice_details.invoice_id')
->join('payment', 'invoice.invoice_id', '=', 'payment.invoice_id')
->where('invoice.client_id', 7)
->select('payment.amount')
->orderBy('invoice.invoice_id', 'DESC')
->get();
I'm using Laravel Query Builder and my join statement working perfectly.
User table columns:
name|email|phone|gender
School_Abouts table columns:
courses|boards|contact|location|teachers
Currently I do the select query as below:
$school=User::join('school_abouts', 'users.id', '=', 'school_abouts.school_id')
->where('users.id',$id)
->select('users.name',
'users.email',
'users.phone',
'school_abouts.courses',
'school_abouts.boards',
'school_abouts.contact',
'school_abouts.location',
'school_abouts.teachers')
->first();
To select the columns from school_about table I have to write table name multiple times. But is there any way to pass an array of columns instead? I tried this but failed:
->select('users.name',
'users.email',
'users.phone',
'school_abouts'.[courses,boards,location,contact,teachers],
)
You can safely remove table name from columns as there is no column name common in both tables but else, as I see, you are trying to get almost all columns from both tables which could be simplified using *:
$school = User::join('school_abouts', 'users.id', '=', 'school_abouts.school_id')
->where('users.id', $id)
->select('users.*', 'school_abouts.*')
->first();
However, if you want to get some columns and their names could make an ambiguity then prefixing column names with table name is a must. To make it shorter you could use aliasing:
$school = User::join('school_abouts AS sa', 'users.id', '=', 'sa.school_id')
->where('users.id', $id)
->select('users.name',
'sa.courses',
'sa.boards',
'sa.contact',
'sa.location')
->first();
I have a question about Laravel queries, so I have a upload Model and database table which stores all my images. Then there is an Activity Model and database table which stores all my activities. For each activity I want a image.
So my Activity model has a 'uploads_id' column. I wrote the query like this:
$activity_images = DB::table('uploads')
->join('activities', 'uploads.id', '=', 'activities.upload_id')
->where('uploads.id', '=', 'activities.upload_id')
->get();
It cannot find the right image what am I doing wrong?
You are "joining" twice in your join and where clause. You connect uploads.id and activities.upload_id one time in the join and again in the where clause.
If you want to query for a special upload.id, your query should look like this:
$activity_images = DB::table('uploads')
->join('activities', 'uploads.id', '=', 'activities.upload_id')
->where('uploads.id', '=', '<yourUploadID>')
->get();
If you want all images, you can delete the where statement.
$activity_images = DB::table('uploads')
->join('activities', 'uploads.id', '=', 'activities.upload_id')
->get();
If you use join an inner join will be used.
You could also use leftJoin if you want all entries from the table uploads.
$activity_images = DB::table('uploads')
->leftJoin('activities', 'uploads.id', '=', 'activities.upload_id')
->get();
Does it solve your issue?
I am performing a query in which desirable output is first apply where clause then after I want to perform right join.I have this query but it perform first join then where.thank you for you any help advance.
Here is my query
$friends = friend_list::where('friend_lists.user_id', '=', $id)
->rightJoin('users as u1', 'u1.id', '=', 'friend_lists.user_id2')
->where('friend_lists.user_id2','!=',$id)
->where('u1.id','!=',$id)
->orwhere('status',null)
->get();
edited:
I am implementing friend request section.
In which user table contains...user(id,name,..,..) friend_list(userid,userid2,status)
in friend_list shows status with other friend.I do right join withfriend_list.if status is null then there is no row for that user with current user.so status is null and it shows add friend
.so null value is important therefor right join with user table
Change the WHERE to another JOIN condition
$friends = friend_list::rightJoin('users as u1', function($join) {
$join->on('u1.id', '=', 'friend_lists.user_id2')
->where('friend_lists.user_id', '=', $id);
})
->where('friend_lists.user_id2','!=',$id)
->where('u1.id','!=',$id)
->orwhere('status',null)
->get();