I am trying to compare two tables to check is user data already exits in another table. I show some posts they talk about whereRaw but details is not enough i was try to run query but i am not getting which i want.
UPDATED
I have 2 tables one is for challenges between two people
Challenge Table id,user_one, user_two, data_one, data_two,winner_id
And my second table is
vote Table id, user_id, battle_id, voted_user
I want to check is user already votes the table or not, If yes skip that challenge table and show remain table data to user.
$challenges = DB::table('challenges')->whereRaw([
['challenges.user_one', '!=', $uid],
['challenges.id', '!=', 'vote.id'],
])->orWhereRaw([
['challenges.user_one', '!=', $uid],
['challenges.id', '!=', 'vote.id'],
])->get();
You can achieve it by using crossJoin
$challenges = DB::table('challenges')->crossJoin('vote')
->where('challenges.user_one', '!=', $uid)
->where('challenges.id', '!=', 'vote.id')
->orWhere('challenges.user_one', '!=', $uid)
->orWhere('challenges.id', '!=', 'vote.id')->get();
Refer: https://laravel.com/docs/5.8/queries
Related
I have a products table that is connected through model_has_attachments with attachments table. I need to connect first attachment to each product record thought the query builder, but for some reason it just give me few records with model_has_attachments ids and rest is the null
my query builder look as:
$products = DB::table('products')->
leftJoin(DB::raw('(select `model_id`, `attachment_id` from model_has_attachments where model_has_attachments.model_id = id) as model_has_attachments'), 'model_has_attachments.model_id', 'products.id')->
leftJoin('attachments', 'model_has_attachments.attachment_id', '=', 'attachments.id')->
select('products.id', 'products.square', 'products.height', 'products.address', 'products.rooms', 'products.title', 'products.description', 'model_has_attachments.model_id as id_model', 'model_has_attachments.attachment_id')->
where([
['products.deleted_at', '=', null],
]);
I've tried to add limit = 1 in the DB::raw but it just give me the first record of the products table, not a joined table. Can you tell me why?
I also tried different approach, but it takes all the record of attachments which result duplicate products records if product has more than one attachment. I also have tried to add ->limit(1) at the end but it just ignores the method.
leftJoin('model_has_attachments', function ($join) {
$join->on('products.id', '=', 'model_has_attachments.model_id')->where('model_has_attachments.model_type', '=', Product::class);
})->
``
//try this
$products = Product::leftJoin('model_has_attachments', 'products.id', '=', 'model_has_attachments.model_id')
->leftJoin('attachments', 'attachments.id', '=', 'model_has_attachments.attachment_id')
->addSelect('products.*', 'attachments.id as attachment_id')
->where('attachments.is_active',1)
->get();
I want to create a chat system on which i could list all the chats between specific 2 persons
I have 2 tables users and chats
my chats table have 3 columns - user_id, friend_id and chat
my User.php model file is like this
public function chats() {
return $this->hasMany('App\Chat');
}
For eg:
I want to list all the chat between user 1 and 3 without changing the order of the conversation
I can simply do it by doing $chats = Auth::user()->chats->where('friend_id', '=', $id); but this will only give the authenticated (which is user 1 or 3) users chats. But I want the conversation between both of them.
So I have found an alternate way to do that by
$first = Chat::all()->where('user_id', '=', Auth::user()->id)->where('friend_id', '=', $id);
$second = Chat::all()->where('user_id', '=', $id)->where('friend_id', '=', Auth::user()->id);
$chats = $first->merge($second);
But this way has some problems. This will not get the chats in the correct order. I think it is impossible to order it correctly.
So my question is how can I list the conversation between two persons in the correct order easily?
If you want more details about my problem you can just ask.
You should be able to do it in one query with parameter grouping, rather than executing two separate queries and then merging them.
Chat::where(function ($query) use ($id) {
$query->where('user_id', '=', Auth::user()->id)
->where('friend_id', '=', $id);
})->orWhere(function ($query) use ($id) {
$query->where('user_id', '=', $id)
->where('friend_id', '=', Auth::user()->id);
})->get();
This might also return your results in the correct order, just because without any sort criteria specified, databases will often return rows in the order they were inserted. However, without adding something to your chat table to sort by, (either a timestamp or an autoincrement id), there's no way to guarantee it.
Try like this
$first = Chat::all()->where('user_id', '=', Auth::user()->id)
->where('friend_id', '=', $id)->get();
$second = Chat::all()->where('user_id', '=', $id)
->where('friend_id', '=', Auth::user()
->id)->get();
$chats = $first->merge($second)
->sortBy('created_at');//created_at is timing added change if other
First of all, you should not do all() before filtering. This is bad because fetches all the table data and then does the filtering in PHP.
You should consider doing this:
In your migration:
Schema::create("chat", function (Blueprint $table) {
//Other creation lines
$table->timestamps();
})
Then in your chat model:
public function scopeInvolvingUsers($query, $userId,$friendId) {
return $query->where([ ["user_id",$userId],["friend_id",$friendId] ])
->orWhere([ ["user_id",$friendId],["friend_id",$userId] ]);
}
Then you can do the following:
$chats = Chat::involvingUsers(\Auth::id(),$otherId)->latest()->get();
Note that latest or earliest requires the timestamps to be present on the table.
I will add timestamps in chat table which will ensure the order.
To add timestamp into chat table just add
$table->timestamps();
and the you can select the chat related to the user and sort it by created_at.
In laravel 5.3+ use
Chats::where(['user_id', '=', Auth::id()], ['friend_id', '=', $id])->orWhere(['user_id', '=', $id], ['friend_id', '=', Auth::id()])->sortBy('created_at');
Chat::whereIn('user_id', [$id, Auth->user()->id])
->whereIn('friend_id', [$id, Auth->user()->id])->get();
How do I get results, where there are no results on the joined table, but only for that user?
For example:
$availableQuests = Upload::where('uploads.approved', 1)
->where('uploads.published', 1)
->where('uploads.available', 1)
->where('uploads.type', 'guide')
->join('completed_guides', 'uploads.id', '=', 'completed_guides.upload_id')
->whereNull('completed_guides.id')
->orderBy('published_at', 'desc')
->take(10)
->get();
The problem with this, this accounts for all users, I need to include completed_guides.user_id somehow, to get all the uploads where the id doesnt match in completed_guides
If that makes sense?
I'm trying to fetch following things from the database:
user name
user avatar_name
user avatar_filetype
complete conversation_messages
with the following query:
static public function getConversation($id)
{
$conversation = DB::table('conversation_messages')
->where('belongsTo', $id)
->join('users', 'conversation_messages.sender', '=', 'users.id')
->join('user_avatars', 'conversation_messages.sender', '=', 'user_avatars.id')
->select('users.name', 'conversation_messages.*', 'user_avatars.name', 'user_avatars.filetype')
->get();
return $conversation;
}
It works fine so far, but the avatar's column name is 'name' like the column name from the 'users' table.
So if I'm using this query the to get the output via $conversation->name, the avatar.name overwrites the users.name
Is there a way to rename the query output like the mysql "as" feature at laravel 5.1?
For example:
$conversation->avatarName
$conversation->userName
Meh okay.. i've found a simple solution here
->select('users.name as userName', 'conversation_messages.*', 'user_avatars.name as avatarName', 'user_avatars.filetype')
As you can mention I've added the requested "as-Feature" next to the table.columnName
Take a look at this example of trying to join three tables staffs, customers and bookings(pivot table).
$bookings = \DB::table('bookings')
->join('staffs', 'staffs.id' , '=', 'bookings.staff_id')
->join('customers', 'customers.id' , '=', 'bookings.customer_id')
->select('bookings.id', 'bookings.start_time', 'bookings.end_time', 'bookings.service', 'staffs.name as Staff-Name', 'customers.name as Customer-Name')
->orderBy('customers.name', 'desc')
->get();
return view('booking.index')
->with('bookings', $bookings);
I had the following problem, simplified example:
$result = Donation::join('user', 'user.id', '=', 'donation.user_id')->where('user.email', 'hello#papabello.com')->first();
$result is a collection of Donation models. BUT CAREFUL:
both tables, have a 'created_at' column. Now which created_at is displayed when doing $result->created_at ? i don't know. It seems that eloquent is doing an implicit select * when doing a join, returning models Donation but with additional attributes. created_at seems random. So what I really wanted, is a return of all Donation models of the user with email hello#papabello.com
solution is this:
$result = Donation::select('donation.*')->join('user', 'user.id', '=', 'donation.user_id')->where('user.email', 'hello#papabello.com')->first();
Yeah, simply rename the column on either table and it should work.
Also what you can do is, rename the user.name column to anything, also rename sender column of conversation_messages to id and perform a natural join.
I am using laravel to create a friend list. Now I want to get all of my friends with the name and avatar and stuff from the USER table.
My schema:
`cid`, `uid_by`, `uid_to`, `status`
uid_by (the inviting user)
uid_to (to be friend user)
status (accepted or ignored)
I only have 1 row per friendship. meaning its a 2 way friendship.
I tried to make a query:
$contacts = DB::table('contacts')
->leftJoin('users', 'contacts.uid_by', '=', 'users.uid')
->where('uid_by', $me)
->orWhere('uid_to', $me)
->where('contacts.status', 'accepted')
->get();
But its giving me some wrong information. Like instead of giving me the friend user info. its giving me my own info. All I want is to get the friends info.
Should I redesign the db? or am I missing something?
update
technically the thing is if uid_by is my user_id then check the uid_to else if the uid_by is not my user_id then check uid_by then use those to get the data from the users table uid column.
So my uid could be on uid_by and my friend on uid_to or vice versa.
But I can't get the query right.
See Advanced wheres:
$contacts = DB::table('contacts')
->join('users', 'contacts.uid_by', '=', 'users.uid')
->where('users.uid','<>',$me)
->where('contacts.status', 'accepted')
->where(function($query)
{
$query-->where('uid_by', $me)
->orWhere('uid_to', $me)
})
->get();