Where in newly create column - mysql

I have newly created column
$query->select([
"table1.*",
DB::raw("
CASE
WHEN table2.updated_at >= table1.updated_at
THEN table2.updated_at
ELSE table1.updated_at
END as last_update
")
]);
Now I want to find table where last_update is between since and till, my current solution:
$query->where(function ($query) {
$query->where("table1.updated_at", '>=', $this->since);
$query->orWhere("table2.updated_at", '>=', $this->since);
});
$query->where(function ($query) {
$query->where("table1.updated_at", '>=', $this->till);
$query->orWhere("table2.updated_at", '>=', $this->till);
});
How can I use 'last_update' column or use where on column with has newer update_at?

$query->having("last_update", '>=', $this->since)
Having resolved my problem.

you can query table1 and join table2 and on both tables you can call the where clause:
Table1::with(['table2' => function ($query) {
$query->where('updated_at', '>=', $this->since);
}])
->where('updated_at', '>=', $this->since)
->get();

Related

Adding OR statements to Eloquent Queries

I need a little help regarding the syntax of Eloquent. I want to add more where clauses but can't get the OR working. I read https://laravel.com/docs/7.x/queries#where-clauses but my statement fails.
Works:
$events = DB::table('events')->select('id','resourceId','title','start','end')
->whereDate('start', '>=', $start)->whereDate('end', '<=', $end)->get();
Does not work:
$events = DB::table('events')->select('id','resourceId','title','start','end')
->whereDate('start', '>=', $start)->whereDate('end', '<=', $end)
->orWhere(function($query) {
$query->whereDate('start', '<=', $start)
->whereDate('end', '>=', $end);
})
->get();
Is orWhere not supposed to work with whereDate?
First; while using closures you need to pass arguments with use. You may or two main conditions and in their nested conditions both sub-conditions will be anded.
public function index()
{
DB::table('events')
->select('id', 'resourceId', 'title', 'start', 'end')
->where(function ($query) use ($start, $end) {
$query->whereDate('start', '>=', $start)->whereDate('end', '<=', $end);
})
->orWhere(function ($query) use ($start, $end) {
$query->whereDate('start', '<=', $start)->whereDate('end', '>=', $end);
})
->get();
}
This function will print (don't mind about the dates, just example)
SELECT `id`, `resourceId`, `title`, `start`, `end`
FROM `events`
WHERE (date(`start`) >= '2020-06-15' and date(`end`) <= '2020-06-16')
or (date(`start`) <= '2020-06-15' and date(`end`) >= '2020-06-16')

Laravel count with where on Query Builder with joins

Good day all, I am trying to count all records in a table but only if the table does not contain data in a specific column (deleted_at). It is a join table the table names are companies and employees. I am currently counting the records with a DB::raw but it should only count it if the deleted_at column is null. Please understand that i am a beginner.
public function index()
{
$user = Auth::user()->id;
$companies = DB::table('companies AS c')
->select([
'c.id',
'c.logo',
'c.company_name',
'c.created_at',
'c.sector',
'c.deleted_at',
DB::raw('COUNT(e.id) AS employee_count')
])
->leftJoin('employees AS e', 'e.company_id', '=', 'c.id' )
->leftJoin('company_user AS cu', 'cu.company_id', '=', 'c.id')
->where('cu.user_id', '=', $user)
->where('c.deleted_at', '=', null)
->groupBy('c.id')
->get();
return view('account.companies.index')
->with('companies', $companies);
}
If you are using Mysql then you could use conditional aggregation
$companies = DB::table('companies AS c')
->select([
'c.id',
'c.logo',
'c.company_name',
'c.created_at',
'c.sector',
'c.deleted_at',
DB::raw('SUM(c.deleted_at IS NULL) AS employee_count')
])
->leftJoin('employees AS e', 'e.company_id', '=', 'c.id' )
->leftJoin('company_user AS cu', 'cu.company_id', '=', 'c.id')
->where('cu.user_id', '=', $user)
->groupBy('c.id')
->get();
In mysql when an expression is used inside sum(a= b) it will result as a boolean 0/1 so you can get your conditional count using above
Or you could use whereNull() method in your query
->whereNull('c.deleted_at')
Use this code:
$employeeCount = DB::table('employees')
->select('companies.name', DB::raw('count(employees.id) as employee_count'))
->join('companies', 'employees.company','=','companies.id')
->groupBy('companies.id')
->get();

How can I use 'AS' in my count query?

How can I use AS in my count query?
Actually i want to result like { "count":"number" } for json result. I dont know what should i call this thing?
public function firstHourTrades(){
$user_id = Auth::user()->id;
$data = DB::table('finaltrade')
->join('exchanges', 'finaltrade.exchange_id', '=', 'exchanges.id')
->where('finaltrade.user_id', $user_id)
->whereTime(DB::raw('IF(finaltrade.buy_datetime<finaltrade.sell_datetime, finaltrade.buy_datetime, finaltrade.sell_datetime) '), '>=', DB::raw('exchanges.start_time'))
->whereTime(DB::raw('IF(finaltrade.buy_datetime<finaltrade.sell_datetime, finaltrade.buy_datetime, finaltrade.sell_datetime) '), '<=', DB::raw("ADDTIME(exchanges.start_time, '1:00:00')"))
->count();
return response()->json($data);
}
You could also do a raw select and manually assign the alias:
$data = DB::table('finaltrade')
->select(DB::raw('count(*) as count'))
->join('exchanges', 'finaltrade.exchange_id', '=', 'exchanges.id')
->where('finaltrade.user_id', $user_id)
->whereTime(DB::raw('IF(finaltrade.buy_datetime<finaltrade.sell_datetime, finaltrade.buy_datetime, finaltrade.sell_datetime) '), '>=', DB::raw('exchanges.start_time'))
->whereTime(DB::raw('IF(finaltrade.buy_datetime<finaltrade.sell_datetime, finaltrade.buy_datetime, finaltrade.sell_datetime) '), '<=', DB::raw("ADDTIME(exchanges.start_time, '1:00:00')"))
->get();

Comparing timestamp and Carbon::now()->toTimeString() without seconds

I am building a query which will be executed every minute when the daily_at time and the current time are equal. The daily_at variable is a timestamp of for example 10:05:33.
I want the where clause in the query to pass when the hour and minute are the same, but not the second else almost non will be executed. The where clause which I have now:
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::now()->toTimeString())
.....
Could someone help me to adjust the where clause to ignore the seconds?
Try with:
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::now()->format('H:i'))
One more way:
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::createFromTime(Carbon::now()->hour,Carbon::now()->minute,00)->format('H:i:s'))
You can pass an extra argument to set timezone:
Carbon::createFromTime(Carbon::now()->hour,Carbon::now()->minute,00,'Example/Zone')->format('H:i:s')
I found the solution. You can use setSeconds(int $value) method:
Carbon::now()->setSeconds(0)->toTimeString()
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::now('Y-m-d H:i')->toTimeString())
use this code
Can you please try with this way:
whereRaw(DATE_FORMAT(daily_at, "%H:%i") = Carbon::now()->format('H:i'))
So final query would be,
DB::table('restaurants')
->where('schedule', '=', $schedule)
->where('active', '=', 1)
->whereDate('start_at', '<=', Carbon::today())
->where('daily_at', '=', Carbon::now()->toTimeString())
->whereRaw(DATE_FORMAT(daily_at, "%H:%i") = Carbon::now()->format('H:i'))

CURDATE() with laravel 5

I'm new to laravel and i am wanting to use multiple where clauses and use curdate().
This is an example :
$data = DB::table('toutcome')->where('date', '>=', curdate())->where('Status', '=', 'A')->count('AppID');
return view('home', compact('data'));
It's not working at all.
So along with the answers in the comments:
public function index()
{
// First query with DB::raw() variant
$data = DB::table('toutcome')
->where('date', '>=', DB::raw('curdate()'))
->where('Status', '=', 'A')
->count('AppID');
// Second query with Carbon variant
$data2 = DB::table('toutcome')
->where('date', '>=', Carbon::now())
->where('Status', '=', 'A')
->count('AppID');
// Third query with '#Sunny' whereRaw variant
$data3 = DB::table('toutcome')
->whereRaw('date >= curdate()')
->where('Status', '=', 'A')
->count('AppID');
return view('home', compact('data','data2','data3'));
}
I'm not a big fan of compact() personally so I would write:
return view('home', ['data'=>&$data,'data2'=>&$data2,'data3'=>&$data3])
although personally (if you want to read on taking it further) read up on ViewComposers:
https://laravel.com/docs/master/views#view-composers
Change
where('date', '>=', curdate())
to
whereRaw('date >= curdate()')