Laravel Eloquent query for left join - mysql

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

Related

How to get last record of duplicate data?

I have table A ( id - message - user_id ), I need to say if any user_id duplicated in table just bring last one that user had added:
My controller code (my wrong shut):
$duplicate = VerfiyRequest::where('user_id', '>' , 1)->first();
$VerfiyRequests = VerfiyRequest::latest()->get();
return view('backend.VerfiyRequest.index' , compact('VerfiyRequests'));
Use this to get the last record of each user by the latest id (incrementing primary key):
VerfiyRequest::whereIn('id', function ($query) {
$query
->from('verify_requests')
->select(DB::raw('MAX(id) as id'))
->groupBy('user_id');
})->get();
Explanation: the MAX(id) as id selects latest id of each user group, so the inner query returns latest record of each user.

How to get "unique" users by combining email and date

I am using Laravel 5.5.
I have a database which contains users. The problem is that some users exist more than one time because of a bug. I want to query my database and select all "unique" users.
By using the word "unique" I mean the below :
If a user with email "test#test.com" exists 50 times I want the row that created_at is closest to now.
My query, which returns all users is written below :
DB::table('users')
->select('name', 'surname', 'email', 'phone', 'answers', 'newsletter', 'created_at')
->get();
I got confused and I'm not sure if i should use limit combining it with order by created_at column.
Any ideas?
Ok, this is what you need to do: First off, you get a table with the users in their last created_at 'version'. Now you have a list of emails and dates. Then you perform a left join of all the users with that temporary table.
TL;DR:
$users = DB::select('select t1.* from users t1 right join (SELECT email, MAX(created_at) as created_at from users group by email) as t2 on t1.email=t2.email and t1.created_at=t2.created_at');
I hate raw SQL, and I hate subqueries, but this is the only way I know using generic SQL (I mean, you could do a better MySQL or MSSQL native queries, but this should do for you.)
You can use
DB::table('users')->select('name', 'surname', 'email','phone','answers','newsletter','created_at')->orderBy('created_at', 'desc')->groupBy('email')->get();
For more help refer Order By before Group By using Eloquent (Laravel)
What you need is groupby and orderby
try this code
DB::table('users')->select('name', 'surname', 'email','phone','answers','newsletter','created_at')
->orderBy('created_at', 'desc')
->groupBy('email')
->get();
hope it will help you if you need further info try above link!
To get latest user record among duplicates you can use a self join
DB::table('users as u')
->select('u.*')
->leftJoin('users as u1', function ($join) {
$join->on('u.email', '=', 'u1.email')
->whereRaw(DB::raw('u.created_at < u1.created_at'));
})
->whereNull('u1.id')
->get();
In plain SQL it would be something like
select u.*
from users u
left join users u1 on u.email = u1.email
and u.created_at < u1.created_at
where u1.id is null

JOIN after WHERE clause in laravel

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

complex sql join table

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

How can I select with count() on specific user in Laravel?

Here is my Database structure:
Also - there is a table users and reciever_id references that table id.
I use that query to get count of each type of notifications as well as data for that type of notifications from notification_types table.
Notification::
select('notification_types.*', DB::raw('count(*) as total'))
->join('notification_types', 'notifications.type_id', '=', 'notification_types.id')
->groupBy('notifications.type_id')
->get()
What I need - is to set constraint on reciever_id, I just don't get - where should I put the where clause?
Just chain the where method anywhere before get, since your condition will be applied on the notifications table:
Notification::select('notification_types.*', DB::raw('count(*) as total'))
->join('notification_types', 'notifications.type_id', '=', 'notification_types.id')
->where('reciever_id', $receiverId)
->groupBy('type_id')
->get();
Also, there's no need with this query to group by notifications.type_id, type_id will do, because there are no ambiguities created here because there are no other columns named type_id.