Laravel 4 advanced wheres - laravel

I have my query working perfectly in mySQL, however am struggling to use the advanced wheres inside the laravel query builder.
Can anyone assist in converting this at all?
So far I have:
LARAVEL
$start_request = '2014-12-18 09:00';
$end_request = '2014-12-18 10:00';
$events= DB::table('events')
->where('hotel_id', 4)
->orWhere(function($query)
{
$query->where($start_request, '<=', 'start_time')
->where($end_request, '>', 'start_time');
})
->orWhere(function($query)
{
$query->where($start_request, '>=', 'start_time')
->where($end_request, '<', 'end_time');
})
->get();
mySQL
SELECT id, title, description, start_time, end_time FROM events where hotel_id = 4 and (('2014-12-18 09:00' <= start_time and '2014-12-18 10:00' > start_time)
or ('2014-12-18 09:00' >= start_time and '2014-12-18 10:00' < end_time));

Can you try this?
$start_request = '2014-12-18 09:00';
$end_request = '2014-12-18 10:00';
$events= DB::table('events')
->where('hotel_id', 4)
->where(function($query) use($start_request, $end_request) {
$query->where(function($subquery) use($start_request, $end_request){
$subquery->where('start_time', '>=', $start_request)
->where('start_time', '<', $end_request);
});
$query->orWhere(function($subquery1) use($start_request, $end_request) {
$subquery1->where('start_time', '<=', $start_request)
->where('end_time', '>', $end_request);
});
})
->get();

Something like this should do the job:
$start_request = '2014-12-18 09:00';
$end_request = '2014-12-18 10:00';
$events = DB::table('events')
->where('hotel_id', 4)
->where(function ($q) use ($start_request, $end_request) {
$q->where(function ($query) use ($start_request, $end_request) {
$query->where($start_request, '<=', 'start_time')
->where($end_request, '>', 'start_time');
})
->orWhere(function ($query) use ($start_request, $end_request) {
$query->where($start_request, '>=', 'start_time')
->where($end_request, '<', 'end_time');
});
})
->select('id', 'title', 'description', 'start_time', 'end_time')
->get();

Related

Multiple Where Clause in Laravel not working as needed

I am trying to get all the expired listings from the db. the table has three fields for the expiry date, to_date_1, to_date_2, to_date_3.
date 2&3 may have a null value but date 1 always has a value. If date 3 is not null I want the query to compare with date 3 and skip date1 &2. if date 3 is null, the query should compare with date 2, otherwise date 1 will be the expiry date. here is my query.
$query = Listing::query()
->where('vendor_id', $vendor->id)
->where('is_deleted', 0)->where('is_published', 1)->where('is_approved', 1)
->where(function ($q) {
return $q->WhereNotNull('to_date_3')->Where('to_date_3', '<', \Carbon\Carbon::now()->format('Y-m-d'));
})
->where(function ($q) {
return $q->WhereNotNull('to_date_2')->Where('to_date_2', '<', \Carbon\Carbon::now()->format('Y-m-d'));
})
->where(function ($q) {
return $q->orWhere('to_date_1', '<', \Carbon\Carbon::now()->format('Y-m-d'));
})
->orderBy('created_at', 'desc');
$listings = $query->paginate(10);
Here is a sample data:
id
from_date_1
to_date_1
from_date_2
to_date_2
from_date_3
to_date_3
1
2021-06-10
2021-08-15
2021-08-16
2021-08-31
2021-09-01
2021-09-15
2
2021-06-25
2021-08-10
2021-08-11
2021-08-22
NULL
NULL
3
2021-06-25
2021-08-20
NULL
NULL
NULL
NULL
if today date is: 21-08-2021, the result should be record: 1 & 2
As Pavlo said group your query inside a where
$query = Listing::query()
->where(function ($query) { // Wrap you code inside a where
$query->where('vendor_id', $vendor->id)
->where('is_deleted', 0)->where('is_published', 1)->where('is_approved', 1)
->where(function ($q) {
return $q->WhereNotNull('to_date_3')->Where('to_date_3', '<', Carbon::now()->format('Y-m-d'));
})
->where(function ($q) {
return $q->WhereNotNull('to_date_2')->Where('to_date_2', '<', Carbon::now()->format('Y-m-d'));
})
->where(function ($q) {
return $q->orWhere('to_date_1', '<', Carbon::now()->format('Y-m-d'));
});
})
->orderBy('created_at', 'desc');
$listings = $query->paginate(10);
Try use orWhere
->where('is_deleted', 0)->where('is_published', 1)->where('is_approved', 1)
->where(function ($q) {
return $q->WhereNotNull('to_date_3')->Where('to_date_3', '<', \Carbon\Carbon::now()->format('Y-m-d'));
})
->orWhere(function ($q) {
return $q->WhereNotNull('to_date_2')->Where('to_date_2', '<', \Carbon\Carbon::now()->format('Y-m-d'));
})
->orWhere(function ($q) {
return $q->orWhere('to_date_1', '<', \Carbon\Carbon::now()->format('Y-m-d'));
})
More about parameters grouping
UPDATING (where -> orWhere -> orWhere give you your sql)

Laravel with() Eloquent as variable or another array

I have this Eloquent query that want to display the orders by day, yesterday, week, last week, this month, last month, this year, last year and this is my code however, it does not work or do have any idea to re do the code. In my sample code I do not know how to put into another each with() query with different parameters. Please help.
$product_orders = Product::where('status', 'active')
->with(['order_detail' => function($query) {
$query->with('order');
$query->where('created_at', '>=', today());
}])
->with(['order_detail' => function($query) {
$query->with('order');
$query->where('created_at', '>=', Carbon::yesterday());
}])
->with(['order_detail' => function($query) {
$query->with('order');
$query->where('created_at', '>=', [now()->startOfWeek(), now()->endOfWeek()]);
}])
->with(['order_detail' => function($query) {
$query->with('order');
$query->where('created_at', '>=', [now()->subWeek()->startOfWeek(), now()->subWeek()->endOfWeek()]);
}])
->with(['order_detail' => function($query) {
$query->with('order');
$query->whereYear('created_at', '=', now()->year);
$query->whereMonth('created_at', '=', now()->month);
}])
->with(['order_detail' => function($query) {
$fromDate = Carbon::now()->subMonth()->startOfMonth()->toDateString();
$tillDate = Carbon::now()->subMonth()->endOfMonth()->toDateString();
$parse_fromDate = Carbon::parse($fromDate.' 00:00:00');
$parse_tillDate = Carbon::parse($tillDate.' 23:59:59');
$query->with('order');
$query->whereBetween('created_at',[$parse_fromDate,$parse_tillDate]);
}])
->with(['order_detail' => function($query) {
$query->with('order');
$query->whereYear('created_at', '>=', now()->year);
}])
->with(['order_detail' => function($query) {
$last_year = now()->year - 1;
$query->with('order');
$query->whereYear('created_at', '>=', $last_year);
}])
->get();
With this approach, you're essentially overwriting each "with" with the next one in the chain, so that the only thing that is actually executed is the final "with".
What you will need to do is break these into separate queries, with separate result sets, since, at the core you appear to want result from multiple different queries with different criteria.
$todays_orders = Product::where('status', 'active')
->with(['order_detail' => function($query) {
$query->with('order');
$query->where('created_at', '>=', today());
}])
->get();
$yesterdays_orders = Product::where('status', 'active')
->with(['order_detail' => function($query) {
$query->with('order');
$query->where('created_at', '>=', Carbon::yesterday());
}])
->get();
... etc...
Use the query:
$product_orders = Product::where('status', 'active')
->with([ 'order_detail' => function ($query) {
$last_year = now()->year - 1;
$query->whereYear('created_at', '>=', $last_year);
}, 'order_detail.order' ])->get();
$product_orders->each(function (Product $product) {
$product->today_orders = $product->order_detail->where('created_at', '>=', Carbon::today());
$product->today_orders = $product->order_detail->whereBetween('created_at', [ Carbon::yesterday(), Carbon::today() ]);
$product->weeks_orders = $product->order_detail->whereBetween('created_at', [ Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek() ]);
$product->last_weeks_orders = $product->order_detail->whereBetween('created_at', [ Carbon::now()->subWeek()->startOfWeek(), Carbon::now()->subWeek()->endOfWeek() ]);
// and so on
});
Then in your view each product should have properties that were set in the each
I found my own solution by creating it with filter inside the Model
in Controller
$product_orders = Product::where('status', 'active')
->with('order_detail_today', 'order_detail_yesterday', 'order_detail_this_week',
'order_detail_last_week','order_detail_this_month', 'order_detail_last_month',
'order_detail_this_year', 'order_detail_last_year')->get();
in Model
public function order_detail_today()
{
return $this->hasMany('App\Order_detail','reference_number')
->where('order_type', '!=', 'package')
->with('order')
->where('created_at', '>=', today());
}
public function order_detail_yesterday()
{
return $this->hasMany('App\Order_detail','reference_number')
->where('order_type', '!=', 'package')
->with('order')
->where('created_at', '>=', Carbon::yesterday());
}
public function order_detail_this_week()
{
return $this->hasMany('App\Order_detail','reference_number')
->where('order_type', '!=', 'package')
->with('order')
->where('created_at', '>=', [now()->startOfWeek(), now()->endOfWeek()]);
}
public function order_detail_last_week()
{
return $this->hasMany('App\Order_detail','reference_number')
->where('order_type', '!=', 'package')
->with('order')
->where('created_at', '>=', [now()->subWeek()->startOfWeek(), now()->subWeek()->endOfWeek()]);
}
public function order_detail_this_month()
{
return $this->hasMany('App\Order_detail','reference_number')
->where('order_type', '!=', 'package')
->with('order')
->whereYear('created_at', '=', now()->year)
->whereMonth('created_at', '=', now()->month);
}
public function order_detail_last_month()
{
$fromDate = Carbon::now()->subMonth()->startOfMonth()->toDateString();
$tillDate = Carbon::now()->subMonth()->endOfMonth()->toDateString();
$parse_fromDate = Carbon::parse($fromDate.' 00:00:00');
$parse_tillDate = Carbon::parse($tillDate.' 23:59:59');
return $this->hasMany('App\Order_detail','reference_number')
->where('order_type', '!=', 'package')
->with('order')
->whereYear('created_at', '=', now()->year)
->whereBetween('created_at',[$parse_fromDate,$parse_tillDate]);
}
public function order_detail_this_year()
{
return $this->hasMany('App\Order_detail','reference_number')
->where('order_type', '!=', 'package')
->with('order')
->whereYear('created_at', '>=', now()->year);
}
public function order_detail_last_year()
{
$last_year = now()->year - 1;
return $this->hasMany('App\Order_detail','reference_number')
->where('order_type', '!=', 'package')
->with('order')
->whereYear('created_at', '>=', $last_year);
}

Convert SQL into Laravel Eloquent

I have this SQL query:
SELECT
m1.id
FROM
messages m1
WHERE
m1.to_id = 1 AND m1.created_at < (
SELECT
m2.created_at
FROM
messages m2
WHERE
m2.from_id = m1.to_id AND m2.to_id = m1.from_id)
GROUP BY
m1.id
How can i convert into eloquent? I done this until now, but a don't know what to do in the part of where on subquery.
Message::where('to_id', 1)
->where('created_at', '<', function($q) {
$q->from('messages');
$q->select('created_at');
})
->select('id')
->groupBy('id')
->get();
You can try this:
Message::where('to_id', 1)
->where('created_at', '<', function($q) {
$q->from('messages AS m2')
->select('created_at')
->where('m2.from_id ','=', 'messages.to_id ')
->where('m2.to_id','=','messages.from_id');
})
->select('id')
->groupBy('id')
->get();

Join head table with position table with laravel eloquent

I have the following construction:
(Laravel Version 5.4)
I have a head table (series), and a table with associated positions (posts). The positionstable has three values whose determine, whether the posts should be displayed, or even not. The series table has this information as well.
These columns are: 'published' (boolean), 'published_from' (datetime) and 'published_to' (datetime).
To display the posts, the series and the posts, had to be published (published = 1), and the actual date/time has to be grater, or euqal, than the published_from value, of the series and the post, and the actual date/time has to be lower or equal than the published_to value, as well.
To chek whether the postion should be displayed, I wrote a eloquent scope:
public function scopePublishedRestriction($query)
{
$date = Carbon::today();
$today = date('Y-m-d', $date->getTimestamp());
$query->accessible()
->join('learning_series', function ($join) use ($today) {
$join->on($this->table . '.learning_serie_id', 'learning_series.id')
->where('learning_series.published', 1)
->whereDate('learning_series.published_from', '<=', $today)
->where(function ($join) use ($today) {
$join->orWhere(function ($join) use ($today) {
$join->whereDate('learning_series.published_to', '>=', $today);
})
->orWhere('learning_series.published_to', '0000-00-00 00:00:00');
});
})
->where($this->table . '.published', 1)
->where($this->table . '.published_from', '<=', $today)
->where(function ($query) use ($today) {
$query->orWhere(function ($query) use ($today) {
$query->whereDate($this->table . '.published_to', '>=', $today);
})
->orWhere($this->table . '.published_to', '0000-00-00 00:00:00');
});
return $query;
}
The created SQL-statement is correct,
select * from `brshop_docs_learning_posts`
inner join `brshop_docs_learning_series` on `brshop_docs_learning_posts`.`learning_serie_id` = `brshop_docs_learning_series`.`id`
and `brshop_docs_learning_series`.`published` = ?
and date(`brshop_docs_learning_series`.`published_from`) <= ?
and ((date(`brshop_docs_learning_series`.`published_to`) >= ?) or `brshop_docs_learning_series`.`published_to` = ?)
where `brshop_docs_learning_posts`.`visible` = ?
and `brshop_docs_learning_posts`.`active` = ?
and `brshop_docs_learning_posts`.`published` = ?
and `brshop_docs_learning_posts`.`published_from` <= ?
and ((date(`brshop_docs_learning_posts`.`published_to`) >= ?) or `brshop_docs_learning_posts`.`published_to` = ?)
and `brshop_docs_learning_posts`.`deleted_at` is null
I think, the merge of the collections is wrong. For example, every post in this collection has the ID of the series. So every column, that exists in the series table and in the posts table has the value of the series table.
Thank you for your help ;-)
Markus
I solved it with whereHas()
public function scopePublishedRestriction($query)
{
$date = Carbon::today();
$today = date('Y-m-d', $date->getTimestamp());
$query->accessible()
->whereHas('serie', function($query) use($today){
$query->where('learning_series.published', 1)
->whereDate('learning_series.published_from', '<=', $today)
->where(function ($query) use ($today) {
$query->orWhere(function ($query) use ($today) {
$query->whereDate('learning_series.published_to', '>=', $today);
})
->orWhere('learning_series.published_to', '0000-00-00 00:00:00');
});
})
->where($this->table . '.published', 1)
->where($this->table . '.published_from', '<=', $today)
->where(function ($query) use ($today) {
$query->orWhere(function ($query) use ($today) {
$query->whereDate($this->table . '.published_to', '>=', $today);
})
->orWhere($this->table . '.published_to', '0000-00-00 00:00:00');
});
return $query;
}

Laravel query with relationships and conditions

Hi I have 3 tables in DB. Here is my query:
$nav = PageNav::with([
'page' => function($query) {
$query->where('status', 1)
->where(function($query) {
$query->whereNull('publish_up')
->whereNull('publish_down');
})
->orWhere(function ($query) {
$query->where('publish_up', '<', date('Y-m-d H:i:s'))
->where('publish_down', '>', date('Y-m-d H:i:s'));
});
},
'langs' => function ($query) use ($lang) {$query->where('language_code', '=', $lang);},
])
->get();
It generates this queries:
When I loop $nav there are still pages with status = 0. I really don't understand why? Any suggestions?
As with any SQL query or Eloquent query, OR completely separates the conditions, so as soon as you have an orWhere in eloquent, it will match anything that matches before the OR or after the OR.
You can resolve this by using a nested where, or parentheses in SQL, to properly encapsulate the conditions.
$query->where('status', 1)
->whereNested(function($q1) {
$q1->where(function($query) {
$query->whereNull('publish_up')
->whereNull('publish_down');
})
->orWhere(function ($query) {
$query->where('publish_up', '<', date('Y-m-d H:i:s'))
->where('publish_down', '>', date('Y-m-d H:i:s'));
});
});
Ok I found solution. Needed to wrap condition to whereHas
$nav = PageNav::whereHas('page', function ($query) {
$query->where('status', 1)
->whereNested(function($q1) {
$q1->where(function($query) {
$query->whereNull('publish_up')
->whereNull('publish_down');
})
->orWhere(function ($query) {
$query->where('publish_up', '<', date('Y-m-d H:i:s'))
->where('publish_down', '>', date('Y-m-d H:i:s'));
});
});
})
->with([
'page',
'langs' => function ($query) use ($lang) {
$query->where('language_code', '=', $lang);
}
])
->get();

Resources