Can I update a single row by maximum id using eloquent/fluent - mysql

I have the following query:
$row = Notification::where('from_user_id', '=', Auth::id())
->where('to_user_id', 0)->update(['to_user_id' => $obj]);
which works but how do I update just ONE row? I was hoping to use maximum id for example ->max('id') but I've tried numerous ways of implementing but im having no luck. Or could I use timestamps to distinguish uniqueness?
id|from_user_id|to_user_id |created_at|updated_at
1 | 8 | 0 |2015-04-09|2015-04-09
2 | 8 | 0 |2015-04-09|2015-04-09
I'm actually iterating through my $obj variable and so it changes simply because it's part of an array which is why I only want to update just one of the rows.

You can get the last row (based on created_at field):
$row = Notification::where('from_user_id', '=', Auth::id())
->where('to_user_id', 0)
->orderBy('created_at', 'desc')
->first();
And update the to_user_id on that row:
$row->to_user_id = YOUR_TO_USER_ID;
$row->save();

You are missing the '=' sign on second where clause and update values have to be array type, the query should be
$row = Notification::where('from_user_id', '=', Auth::id())
->where('to_user_id','=', 0)->update(array('to_user_id' => $obj));

Related

Laravel - query the same column with two conditions

I want to get all the datas that were created 30-365 days ago. Tried following codes but it's not working.
Database:
id created_at
1 2022-05-09
2 2021-06-08
Here id 2 was created before 365 days from today(2022-06-10), so it should not be shown. However id 1 was created before 30 days but not more than 365 days. So only id 1 should be shown.
Code 1:
$today = Carbon::now();
$doubtfulLoan = Loan::select('*')
->where(function($query) use ($today) {
return $query
->where('created_at', '<', $today->subDays(30)->endOfDay())
->where('created_at', '>=', $today->subDays(365)->endOfDay());
})
->get();
Output: it gives empty array
P.S if the 2nd where clause is commented, it gives both the ids and if the 1st where clause is commented, it gives id 1 only. But keeping both the condition gives empty array. What am I doing wrong?
Code 2:
$today = Carbon::now();
$doubtfulLoan = Loan::select('*')
->where([
['created_at', '<', $today->subDays(30)->endOfDay()],
['created_at', '>=', $today->subDays(365)->endOfDay()]
])->get();
Output: it gives both the array.
Thanks in advance.
You need to get into the habit of using CarbonImmutable to prevent nasty surprises like this. Use this code:
$today = CarbonImmutable::now();
$doubtfulLoan = Loan::select('*')
->where(function($query) use ($today) {
return $query
->where('created_at', '<', $today->subDays(30)->endOfDay())
->where('created_at', '>=', $today->subDays(365)->endOfDay());
})
->get();
This is because you are doing $today->subDays(30)->endOfDay() which changes the instance value of the carbon instance and then doing $today->subDays(365)->endOfDay() which changes it again. This is however the same instance, so the query builder will do:
SELECT * FROM loans WHERE created_at < '395 days ago' and created_at >= '395 days ago'
since you have passed the same instance. This obviously is never satisfied.
Using the CarbonImmutable class makes all your Carbon objects immutable and any modifications will create a new instance and will not modify the existing instance.
use laravel between method here
$doubtfulLoan = Loan::select('*')
->whereBetween('created_at',[
today()->subDays(365)->startOfDay(),
today()->subDays(30)->endOfDay()
])->get();

How to build query for multiple condition for same column in laravel query builder?

I want to get count from 'user' table with 'plan_validity' is null or more than today's date. both condition need to check for same column with user_id and status = 1.
$currentUser = User::where('user_id', $card_details->user_id)
->where('status', 1)
->where(function (Builder $query) {
return $query
->whereDate('plan_validity', '>=', Carbon::now())
->orWhere('plan_validity', null);
})->count();
giving error
[2021-11-23 10:40:31] production.ERROR: Argument 1 passed to App\Http\Controllers\ProfileController::App\Http\Controllers\{closure}() must be an instance of App\Http\Controllers\Builder, instance of Illuminate\Database\Eloquent\Builder given, called in /home/hellovcard/public_html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php on line 237 {"userId":17,"exception":"[object] (TypeError(code: 0): Argument 1 passed to App\\Http\\Controllers\\ProfileController::App\\Http\\Controllers\\{closure}() must be an instance of App\\Http\\Controllers\\Builder, instance of Illuminate\\Database\\Eloquent\\Builder given, called in /home/hellovcard/public_html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php on line 237 at /home/hellovcard/public_html/app/Http/Controllers/ProfileController.php:34)
how to modify above mentioned query?
this is output I need to get
enter image description here
You are not combining your "where" clauses properly. With the "orWhere" at the end, it essentially ignores all the conditions (ie. which user it relates to) of the preceding where clauses, so adds to the results any row where plan_validity is null. So after you query by user ID and status, you then need to combine the remainder of the query into a logical group like so :
$user = Users::where('user_id', $card_details->user_id)
->where('status', 1)
->where(function (Builder $query) {
return $query
->whereDate('plan_validity', '>=', Carbon::now())
->orWhere('plan_validity', null);
})
->get();

How do I take all the values of a single row under the few id s in PHP Laravel?

This is the output of the select query & I used join query from three tables. How do I take all the values of a single row of id=5 and all of the values of a single row of id=7?
$data = DB::table('col3')
->join('col2', 'col2.Record_ID', '=', 'col3.Record_ID')
->join('col1', 'col1.Record_ID', '=', 'col2.Record_ID') ->select('col1.*', 'col2.*', 'col3.*')
->orderBy('col1.Time','desc')
->get();
If I'm not mistaken, is this not just a case of adding a where clause:
$data = DB::table('col3')
->join('col2', 'col2.Record_ID', '=', 'col3.Record_ID')
->join('col1', 'col1.Record_ID', '=', 'col2.Record_ID') ->select('col1.*', 'col2.*', 'col3.*')
->whereIn('{table that has the ID e.g col1}.id', [5,7])
->orderBy('col1.Time','desc')
->get();

checking for multiple values in a single column in laravel 5

So I'm not sure whether I asked the question well. I'm new to laravel and right now I'm building an application where I need to fetch data for a user if certain conditions are met. This is what I'm trying to achieve:
Select from database where userid = $user and userstatus = active or inactive. or pending.
So all rows with the user id($user) and status(active, inactive and pending) will be returned.
I tried doing:
$users = DB::table('users')
->where('status', '=', 'active')
->orwhere('status', '=', 'inactive')
->orwhere('status', '=', 'pending')
->get();
This returned all the data in that particular table. What is the best way to go about this.
You have at least two options for how to do this you can use, including both so you have one for use in this case and one for general usage. Using a function in where creates a new block, so works like adding parentheses to your query
$users = DB::table('users')
->where('id', $user)
->where(function($query) {
$query->where('status', 'active')
->orWhere('status', 'inactive')
->orWhere('status', 'pending');
})->get();
or
$users = DB::table('users')->where('id', $user)->whereIn('status', ['active', 'inactive', 'pending'])->get();
You can do it as:
$users = DB::table('users')
->where('userid', $userid)
->whereIn('status',['active', 'inactive','pending'])
->get();

Multiple wheres in Laravel join

I have:
$buyingNet = DB::table('parts_enquiries_buying AS PEB')
->select(DB::raw('SUM((PEB.quantity*PEB.net)/IF(ISNULL(currencyRate), rate, currencyRate)) AS total'))
->join('currencies_rates AS CR', function ($q) {
$q->on('CR.id', '=', 'PEB.currencyId')
//->where(DB::raw('YEAR(CR.date)'), '=', date('Y'))
->where(DB::raw('MONTH(CR.date)'), '=', date('m'));
})
->leftJoin('jobs', 'jobs.enquiryId', '=', 'PEB.enquiryId')
->leftJoin('invoices_out AS IO', 'IO.jobId', '=', 'jobs.id')
->where('PEB.enquiryId', $enquiryId)
->first()->total;
If I uncomment the where that matches the year I get null returned, but all the rows that should be there are there.
Is my syntax correct? It should translate as:
... YEAR(CR.date) = ? AND MONTH(CR.date) =? ...
I believe the issue here is that Query builder doesn't understand your DB::raw statement within the ->where clause.
You should do as folllows:
->whereRaw("YEAR(CR.date) = '". date('Y')."'")
->whereRaw("MONTH(CR.date) = '". date('n')."'")
for the month clause you need to use n instead of m since MySQL MONTH returns a single digit for months below 10.