Adding OR statements to Eloquent Queries - mysql

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

Related

Where in newly create column

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

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

Laravel query builder advanced wheres AND, OR

$query = new TableA;
$query = $query->join('tableB', 'tableA.b_id', '=', 'tableB.id');
$query = $query->where('tableB.something', '=', '1');
$query = $query->where('tableA.something_else', '=', '2');
And it produces:
WHERE something=1 AND something_else=2 AND .. AND....
BUT now - I need this:
WHERE something=1 AND something_else=2 AND (city=city1 OR city=city2 OR city=city3) AND (country=country1 OR country=country2)
Any ideas?
Make use of Advanced Wheres. For your example, it'd be something like this:
->where(function ($query) {
$query->where('city', '=', city1)
->orWhere('city', '=', city2)
->orWhere('city', '=', city3);
})->where(function ($query) {
$query->where('country', '=', country1)
->orWhere('country', '=', country2);
});
Quick method. Read about raw expressions:
http://laravel.com/docs/queries#raw-expressions