Laravel search for the close results - laravel

My app has an option to battle another player.
In order to match a player with another, I created a database field named score in my users table.
My goal is to match user with a another random user who is already SEARCHING for a battle. Both of the users has to be on +-100 score difference.
For example, user with score of 100 can battle players with score of 0-200.
I'm trying to search for all of the available options, but couldn't get how to do this.
Currently, I just output the first one in SEARCHING mode.
$pvp = PvpBattle::where('mode','=','SEARCHING')
->first();
How I can get all PvpBattle objects where the associated player1_id has +- 100 score difference from $this->me->score?

Try This code
WhereHas('users') is the user relation between PvpBattle and user
$minScore = $this->me->score - 100;
$maxScore = $this->me->score + 100;
$pvp = PvpBattle::where('mode','=','SEARCHING')
->WhereHas('users', function ($query) use ($minScore, $maxScore){
$query->Where(function ($subQuery) use ($minScore, $maxScore){
$subQuery->orWhere('score', '<=', $maxScore)
->orWhere('score', '>=', $minScore);
});
})
->first();

First find the score of player one to $scoreA or use $this->me->score
Then
$opp_list=PvpBattle::where('mode','=','SEARCHING')->Where(function($query)
{
$query->where('score', '>=', $scoreA -100)
->orwhere('score', '<=', $scoreA+100);
})
->get();
This gets all the players in mode searching with condition score +-100. first() returns the first result from the table.
How are you going to handle two requests at the same time pointing to the same user?
User A should be not returned as a result.
Add ->where('user_id', '!=', $user_id) to query

Use a join with the users table to filter the result by the score of the related user.
$pvps = PvpBattle::join('users', 'users.id', '=', 'pvpbattle.user_id')
->where('pvpbattle.mode','=','SEARCHING')
->where('users.score', '>=', $this->me->score - 100)
->where('users.score', '<=', $this->me->score + 100)
->get()
;

Related

How can I write Laravel eloquent query (inner query) for this plain SQL query

SELECT *
FROM (
SELECT *
FROM appointments
WHERE `date` <= Curdate()
) `t`
WHERE `t`.`end_time` <= current_time
How can I write a Laravel eloquent equivalent query for this SQL query?
If you want to query:
all past appointments (from start to yesterday, based on date field) +
all today appointments that have end_time not past (or exactly now) for today
And assuming you have a proper Model for the appointment table you could try something like :
Appointments::where('appointments.date', '<', Carbon::now()->toDateString())
->orWhere(function ($query) {
$query->where('appointments.date', Carbon::now()->toDateString())
->where('appointments.end_time', '<=', Carbon::now()->toTimeString());
});
You may need to test the Carbon format used in where clauses to be sure it matches your database storage format, and the query return expected results.
I am not sure whether this suit you, you can try it:
Appointment::whereIn('id', function($query) {
$query->select('id')
->from('appointment')
->where('date', '<=', DB::raw('CURDATE()'));
})
->where('end_time', '<=', DB::raw('CURRENT_TIME()'));
Try this i hope you got your solution .
Appointment::whereExists(function ($query){ $query->selectRaw(1) ->from((new
Appointment())->getTable()) ->whereDate("date",'<=',now()->format('Y-m-d')); })-
>whereDate("end_time",'<=',now()->format('H:i:s'))->get()

I want to find the value who exist in array

I have 2 queries and I would like to know the elements (date_debut) of the second query which exists in the first query (dateincal). The elements of the second query can appear one or more times in the first query.
once the dates (date debut) (dateincal) have been found i want to be able to then retrieve also the other information for the element found
$feries = Jourferie::Select('dateincal', 'description')
->where('dateincal', '>=', Carbon::now()->startOfMonth())
->where('dateincal', '<=', Carbon::now()->endOfMonth())
->get();
$plannings = Planning::Select('date_debut', 'id', 'agent_id', 'site_id')
->where('id', '!=', 0)
->where('statut', 'provisoire')
->get();
I don't know if that way can help you:
foreach($feries as $ferie){
$myresult = $plannings->contains('date_debut',$ferie->dateincal)
/* do things */
}

Using day, Month or Year as MYSQL query filter in Laravel

In my code, i am querying a database by accepting month and year input from user.
I have tried writing it the normal PHP way and other ways i can find online but none seems to be working. here is the code i am using currently
$salesmonth = $request->input('mn');
$salesyear = $request->input('yr');
$id = Auth::user()->id;
$comm = \DB::table('bakerysales')
->where([
['customer_id', '=', $id], [MONTH('sales_date'), '=', $salesmonth], [YEAR('sales_date
'), '=', $salesyear]
])
->get();
return view::make('showCommission')->with('comm', $comm);
I expect the query to return data from rows that match user selected month and year
Laravel comes with a few different where clauses for dealing with dates e.g.
whereDate / whereMonth / whereDay / whereYear.
This means that your controller method can look something like:
$comm = \DB::table('bakerysales')
->where('customer_id', auth()->id())
->whereMonth('sales_date', $request->input('mn'))
->whereYear('sales_date', $request->input('yr'))
->get();
return view('showCommission', compact('comm'));

Counting columns with if conidition in query

Counting only columns in which, Buy_Rate is more than Sell_Rate.
My query is not resulting as per expected, it is resulting me wrong.
$user_id = Auth::user()->id;
$losing_trades_count = FinalTrade::where('user_id', '=', $user_id)->where('buy_rate', '<', 'sell_rate')->get()->count();
Inverse: If sell_rate is more than buy_rate then only, count the columns.
You can use whereColumn
$losing_trades_count = FinalTrade::where('user_id', '=', $user_id)
->whereColumn('buy_rate', '<', 'sell_rate')
->count();
Also there is no need to call get() when you need count() from query builder
laravel eloquent where don't support comparing columns. so you need use raw SQL in order to compair two columns. you can do something like,
$user_id = Auth::user()->id;
$losing_trades_count = FinalTrade::where('user_id', '=', $user_id)->whereRaw('buy_rate < sell_rate')->get()->count();
hope this helps!

Querying related table data with Eloquent

i have a problem trying to get records from a model based on a related table.
I have two tables one called leads and one called recycle_logs, my app will basically send the same record in the leads table like once a month, and when it does so i'll store a new record in recycle_logs.
The problem is that i need to select all leads with a specific campaign_id value and that have a specific status that is different from invalid, so far so good, now the problem is i need to get them only if they don't have any recycleLogs associated with them OR if the last recycleLog associated with that particular lead is older than 30 days ago for instance.
What i currently have looks somewhat like this.
$leads = $this->leadModel->where(Lead::CAMPAIGN_ID, $this->campaignID)
->where(Lead::DUPLICATED, Lead::DUPLICATED_NO)
->where(Lead::LEAD_STATUS, "!=" ,Lead::LEAD_STATUS_INVALID)
->orderBy(Lead::CREATED_AT, 'desc')
->with(
['leadRecyclingLog' => function($query) {
$query->where(LeadRecyclingLog::CREATED_AT, '<', (new Carbon())->subDays($this->configRecyclingDays))
->orWhere(LeadRecyclingLog::ID, null);
}]
)
->get();
What exactly am i doing wrong? It always selects the same number of records regardless of me adding or removing recycleLogs
I've managed to get it done through a raw SQL query which i'll post below in case it helps anyone, i'd still like to know how to do it in Eloquent/Query Builder.
SELECT * FROM `leads` LEFT JOIN `lead_recycling_logs` ON `leads`.`guid` = `lead_recycling_logs`.`original_lead_guid` WHERE `leads`.`campaign_id` = :campaignID AND `leads`.`duplicated` = 0 AND `leads`.`lead_status` != :invalidStatus AND (`lead_recycling_logs`.`id` IS NULL OR `lead_recycling_logs`.`created_at` < :recyclingDate) ORDER BY `leads`.`created_at` DESC
Try this:
$leads = $this->leadModel->where(Lead::CAMPAIGN_ID, $this->campaignID)
->where(Lead::DUPLICATED, Lead::DUPLICATED_NO)
->where(Lead::LEAD_STATUS, "!=" ,Lead::LEAD_STATUS_INVALID)
->orderBy(Lead::CREATED_AT, 'desc')
->where(function($q) {
$q->whereHas('leadRecyclingLog', function($q) {
$q->where(LeadRecyclingLog::CREATED_AT, '<', (new Carbon())->subDays($this->configRecyclingDays));
})
->orWhereHas('leadRecyclingLog', '<', 1); // Where count of the relationship is smaller than 1
})->get();
I assumed the first part of the query is working well (up until the relationship).
What you're looking for is ->whereHas(relationship), not ->with(relationship). ->with(relationship) will attach the associated results to the original model (the query for the original model will not be affected by ->with()). ->whereHas(relationship) filters the original model by the condition.
Got it to work through #devk 's help
$leads = $this->leadModel->where(Lead::CAMPAIGN_ID, $this->campaignID)
->where(Lead::DUPLICATED, Lead::DUPLICATED_NO)
->where(Lead::LEAD_STATUS, "!=" ,Lead::LEAD_STATUS_INVALID)
->orderBy(Lead::CREATED_AT, 'desc')
->where(function($q) {
$q->whereHas('leadRecyclingLog', function($q) {
$q->where(LeadRecyclingLog::CREATED_AT, '<', (new Carbon())->subDays($this->configRecyclingDays));
})
->doesntHave('leadRecyclingLog', 'or');
})->get();

Resources