complex sql join table - mysql

I have 4 table
chart, chart_detail, customer, produk
like this
I wanna run sql comand to list data in chart table
I don't have problem to join cart table with chart detail & customer table
because
chart.id = chart_detail.id_chart
chart.id_customer = customer.id
DB::table('chart')
->join('customer', 'chart.id_customer', '=', 'customer.id')
->join('chart_detail', 'chart.id', '=', 'chart_detail.id_chart')->get();
but i have problem can't access nama_produk
( in chart_detail table there is only id_produk)...so i need to join chart table with produk table
DB::table('chart')
->join('customer', 'chart.id_customer', '=', 'customer.id')
->join('produk', 'produk.id', '=', 'chart_detail.id_produk')
->join('chart_detail', 'chart.id', '=', 'chart_detail.id_chart')->get();
but i get error like this
Column not found: 1054 Unknown column 'chart_detail.id_produk' in 'on clause'
because in chart table there is not available id_produk
id_produk available in chart_detail table
i wonder how to solve it

You had your joins out of order, hence the error about the unknown column. Try the following code:
DB::table('chart')
->join('customer', 'chart.id_customer', '=', 'customer.id')
->join('chart_detail', 'chart.id', '=', 'chart_detail.id_chart')
->join('produk', 'produk.id', '=', 'chart_detail.id_produk')->get();

Related

Laravel Eloquent query for left join

I have two tables available. 1) Users 2) Friendships. Following is the table structure:
Users Table have following columns
id
email
dob
password
first_name
last_name
username
gender
phone
country
Friendships table have following columns
id
sender_id
recipent_id
status
created_at
updated_at
Now I want to retrieve data from the "users" table using the "sender_id," which is the same as the "id" in the "users" table.
I'm using the left join to perform the required query as follow:
public function show_friend_request(){
$user_id = auth()->user()->id;
**//Below query will get the userID's of people who have sent the request to current user.**
$get_friend_requests = DB::table('friendships')->where('recipient_id',$user_id)
->where('status','pending')->get(['sender_id'])->first()->sender_id;
$show_friend_request_Data = DB::table('users')
->leftJoin('friendships', 'sender_id', '=', $get_friend_requests)
->get();
return $show_friend_request_Data ;
}
But when i executed the above code i'm getting the following error:
Illuminate \ Database \ QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.sender_id' in 'on clause'
select * from `users` left join `friendships` on `users`.`sender_id` = `63b8760f-826b-4c1c-aea9-23f1dff148db`
All you have to do is:
$show_friend_request_Data = DB::table('users')
->leftJoin('friendships', 'friendships.sender_id', '=', 'users.id')
->where('users.id', '=', $get_friend_requests)
->get();
I also suggest you to think of how to optimise the whole query to only 1 request and also how to get multiple friend requests at the time. Because now you're only getting the first friend pending friend request ;)

Join with inverse of second table in MySQl and Laravel

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();

Mysql join selects multiple column best practice

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();

How to select max aggregate within a subquery with a join in eloquent

I want to select the most recent entry but there are no timestamps(created_at) it can be identified by selecting the max on the primary key. The problem is to this within a subquery and tables needs to be joined.
The query is like:
$prodarr = DB::table('onhand_inventory')
->leftJoin('mapping', 'onhand_inventory.sku', '=', 'mapping.sku')
->where('mapping.mid', function ($query) {
$query->select('mapping.mid')->from('mapping')
->whereRaw('onhand_inventory.sku = mapping.sku')
->max('mapping.mid');
})->leftJoin('order_products', 'order_products.sku', '=', 'onhand_inventory.sku')
->leftJoin('vendors', 'mapping.v_id', '=', 'vendors.vid')
->where('onhand_inventory.shipped_with_box', 0)
->groupBy('onhand_inventory.inv_id')
->orderBy('onhand_inventory.inv_id')
->get();
On executing the above query following error is thrown
Column not found: 1054 Unknown column 'onhand_inventory.sku' in 'where clause'
How to get the onhand_inventory's data to be compared with the mapping's inside the subquery.
You already joined the mapping table so you dont need the sub query.
$prodarr = DB::table('onhand_inventory')
->leftJoin('mapping', 'onhand_inventory.sku', '=', 'mapping.sku')
->leftJoin('order_products', 'order_products.sku', '=', 'onhand_inventory.sku')
->leftJoin('vendors', 'mapping.v_id', '=', 'vendors.vid')
->where('onhand_inventory.shipped_with_box', 0)
->orderBy('mapping.mid', 'desc')
->groupBy('onhand_inventory.inv_id')
->orderBy('onhand_inventory.inv_id')
->limit(1)
->get();
I didnt run the code but i hope this will help.

Eloquent: filter both pivot table and model table

Eloquent relationship as below:
"stores" belongs to many "storedaytimes" (belong to many)
The pivot table (store_day_time_stores) has a key called "user_id", the storedaytimes table has a field called "date".
I want to filter records in "storedaytimes" based on given "user_id(from pivot table)" and a "start" and "end" date(from storedaytime table).
My current query is
$storedaytime->stores()
->wherePivot('user_id','=',$user)
->orderBy('date')
->where('date','>=',$start)
->where('date','<=',$end)->get();
It's producing a very scary looking query that's not working:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'date' in
'where clause' (SQL: select stores.*,
order_day_time_store.order_day_time_id as
pivot_order_day_time_id, order_day_time_store.store_id as
pivot_store_id, order_day_time_store.user_id as pivot_user_id,
order_day_time_store.id as pivot_id from stores inner join
order_day_time_store on stores.id =
order_day_time_store.store_id where
order_day_time_store.order_day_time_id is null and
order_day_time_store.user_id = 4 and date >= 2017-05-01 12:00:00
and date <= 2017-05-31 12:00:00 order by date asc)
Please help.thank you :3
figured out myself: the following query works:
$storedaytime ->where('date','>=',$start)
->where('date','<=',$end)
->whereHas('stores',function($q) use($user){
$q->where('user_id',$user);})
->get();
Try the following:
$storedaytime->stores()
->wherePivot('user_id','=',$user)
->whereBetween('storedaytimes.date', [$start, $end])
->orderBy('storedaytimes.date')
->get();
It is recommended that the order by clause be at the end of SQL statements, unless you have to order the date beforehand. There is no reason to do it in your case, so place it at the end.