Lavarel - Nested query conditional - php

I have a problem in this code
$query
->where('start_at', '>=', max($campaign->start_at, now()))
->where('end_at', '<=', $campaign->end_at)
->whereNull('deleted_at')
->where('num_posti', '>', function ($query){
$query
->from((new Reservation())->getTable())
->whereColumn('id', '=', 'slots.id')
->whereNull('deleted_at')
->count();
});
The 'slots.id' field doesn't see, but if I execute only the query's first part i see this value.
What is the problem?

Related

Laravel orWhere with left join

I'm not that good with Laravel Eloquent, so be cool pls.
I have 1 product table and 4 "target" tables (sales, novelties, liquidations and exposure).
I'm trying to get all products that have at least one of the four "targets" with this query:
return Product::leftjoin('sales', 'sales.product_id', '=', 'products.id')
->leftjoin('liquidations', 'liquidations.product_id', '=', 'products.id')
->leftjoin('noveltys', 'noveltys.product_id', '=', 'products.id')
->leftjoin('exposures', 'exposures.product_id', '=', 'products.id')
->select('products.*', 'sales.*', 'liquidations.*', 'noveltys.*', 'exposures.*')
->where('noveltys.novelty_end_at', '!=', null)
->orwhere('sales.sale_end_at', '!=', null)
->orWhere('liquidations.liquidation_end_at', '!=', null)
->orWhere('exposures.exposure_end_at', '!=', null)
->get();
Problem is, it only return products that have the first "where" clause true. (In other word, currently, this query only return produtcs with a not null novelty_end_at, it doesn't return products with a sale_end_at and others).
How can I achieve that it also return products with a not null sale_end_at, exposure_end_at and a liquidation_end_at ?
Thank you!
seems a syntax mistake
->orwhere('sales.sale_end_at', '!=', null)
should be
->orWhere('sales.sale_end_at', '!=', null)
also you can try using orWhereNotNull
like
return Product::leftjoin('sales', 'sales.product_id', '=', 'products.id')
->leftjoin('liquidations', 'liquidations.product_id', '=', 'products.id')
->leftjoin('noveltys', 'noveltys.product_id', '=', 'products.id')
->leftjoin('exposures', 'exposures.product_id', '=', 'products.id')
->select('products.*', 'sales.*', 'liquidations.*', 'noveltys.*', 'exposures.*')
->whereNotNull('noveltys.novelty_end_at')
->orWhereNotNull('sales.sale_end_at')
->orWhereNotNull('liquidations.liquidation_end_at')
->orWhereNotNull('exposures.exposure_end_at')
->get();
I found the solution, it's almost the same thing, execpt that I'm using orWhereNotNull and that I'm using DB::table at the start instead of Product::leftjoin directly.
return DB::table('products')
->leftjoin('sales', 'sales.product_id', '=', 'products.id')
->leftjoin('liquidations', 'liquidations.product_id', '=', 'products.id')
->leftjoin('noveltys', 'noveltys.product_id', '=', 'products.id')
->leftjoin('exposures', 'exposures.product_id', '=', 'products.id')
->whereNotNull('sales.sale_end_at')
->orwhereNotNull('noveltys.novelty_end_at')
->orwhereNotNull('liquidations.liquidation_end_at')
->orwhereNotNull('exposures.exposure_end_at')
->get();
Thank you!
Perhaps you could use ->orWhereHas() method. To use this function, you must define the relationship in your Sales and the four target Model classes. Documentation: https://laravel.com/docs/9.x/eloquent-relationships
Then in your query,
return Product::whereHas('noveltys', function(Builder $query) {
// your where clause
})
->orWhereHas('sales', function(Builder $query) {
// your where clause
})
->orWhereHas('liquidations', function(Builder $query) {
// your where clause
})
->orWhereHas('exposures', function(Builder $query) {
// your where clause
})
->get();

Laravel query - getting objects and their counts from related table

I have table articles and it's related tables comments, views and likes which have a field article_id and in my function I am sending name of the related table, with $request['option'], comments for example, with ajax, to get the top 5 most commented articles. But in my function I am getting from the query result with article_ids and counts and then I am iterating through the results with foreach loop and getting article object with article_id that I am sending in the query. I would like to avoid doing that query for each of the results from the first query. What would be the way to do it more elegantly and without so many calls to DB?
This is my code:
public function mostArticle(Request $request) {
$from = $request['from'];
$to = $request['to'];
$result = DB::table($request['option'])
->select(DB::raw('article_id'), DB::raw('count(*) as count'))
->whereDate('created_at', '>=', date($from).' 00:00:00')
->whereDate('created_at', '<=', date($to).' 00:00:00')
->groupBy('article_id')
->orderBy('count', 'DESC')
->take(5)
->get();
foreach($result as $val){
$article = Article::where('id', $val->article_id)->first();
$mostSomethingArticle[$article->id] = [];
$mostSomethingArticle[$article->id]['title'] = $article->title;
$mostSomethingArticle[$article->id]['summary'] = $article->summary;
$mostSomethingArticle[$article->id]['count'] = $val->count;
}
return json_encode($mostSomethingArticle);
}
You can use relations or joins. But im not sure, if this code is correct:
$result = DB::table($request['option'])
->select('article.id', 'article.title', 'article.summary', DB::raw('count('.$request["option"].'.id) as count'))
->join('article', 'article.id', '=', $request['option']."article_id")
->whereDate('created_at', '>=', date($from).' 00:00:00')
->whereDate('created_at', '<=', date($to).' 00:00:00')
->groupBy('article_id')
->orderBy('count', 'DESC')
->take(5)
->get();
return $result;

orderBy is not working in Laravel 5

I am using the below query. orderBy is not working in below query. This query is working in localhost but it is not working in Online Server.
return DB::table('reports')
->leftJoin('sources', 'reports.report_source_id', '=', 'sources.id')
->select('*')
->orderBy('report_id', 'desc')
->take(10)
->get();
Try setting an alias for each table and then using the required alias on the orderBy
If there is a report_id in both tables it will not know which one to use and is probably throwing an error if you look for it.
return DB::table('reports as r')
->leftJoin('sources as s', 'r.report_source_id', '=', 's.id')
->select('*')
->orderBy('r.report_id', 'desc')
->take(10)
->get();
Try this..
use "reports.report_id";
return DB::table('reports')
->leftJoin('sources', 'reports.report_source_id', '=', 'sources.id')
->select('*')
->orderBy('reports.report_id', 'desc')
->take(10)
->all();
Try to use reports.report_id like
return DB::table('reports')
->leftJoin('sources', 'reports.report_source_id', '=', 'sources.id')
->select('*')
->orderBy('reports.report_id', 'desc')
->take(10)
->get();

Laravel Eloquent, return rows where both conditions are True

I have a table of Weeks that is joined to a property table, Weeks table looking like this:-
PropID, WeekDate, Available
1 , 2015-07-04, Yes
1 , 2015-07-11, Yes
1 , 2015-07-18, No
2 , 2015-07-04, Yes
2 , 2015-07-11, No
2 , 2015-07-18, No
I want to select properties where both the weeks of the 4th and 11th are available. In the example above, I want to return two rows with PropID 1 as both are available and no rows from PropID 2 as only one of the weeks are available.
I've tried various ways, but either get nothing or always return the 1st, 2nd and 4th rows.
I think this is close, but it's still missing something as it is looking for dates that are <= AND >=
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where(function($sub)
{
$sub->where('WeekDate', '>=', '2015-07-04');
$sub->where('WeekDate', '<=', '2015-07-11');
});
$q->where('Available', '=', 'Yes');
})
->get();
Not sure this helps, but the Property table is simply
PropID, PropName
1 , Property 1
2 , Property 2
Just found that this SQL works.
SELECT PropID FROM tblweeks WHERE WeekDate IN ('2015-07-04', '2015-07-11') AND Available = 'yes' GROUP BY PropID HAVING COUNT(*) = 2
This will give your result as Property 1 only:
$weeks = Property::whereHas('Week', function ($q) {
$q->where(function ($sub) {
$sub->whereIn('WeekDate', array('2015-07-04', '2015-07-11'));
$sub->where('Available', '=', 'y');
});
$q->groupBy('property_id');
$q->having('count(*)', '=', '2');
})->get();
There are some changes i have did in your query :
Please check this solution
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '=', '2015-07-04');
$q->orWhere('WeekDate', '=', '2015-07-11');
$q->where('Available', '=', 'Yes');
})
->get();
This should work and will return desire output
There are some changes, the query might be using group by query :
Please check this solution
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '=', '2015-07-04');
$q->orWhere('WeekDate', '=', '2015-07-11');
$q->where('Available', '=', 'Yes');
$q->group('WeekDate');
})
->get();
This should work and will return desire output
You actually need two whereHas for this:
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '>=', '2015-07-04');
$q->where('Available', '=', 'Yes');
})
->whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '<=', '2015-07-11');
$q->where('Available', '=', 'Yes');
})
->get();
I believe you do not need the second nested query.
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->where('WeekDate', '>=', '2015-07-04');
$q->where('WeekDate', '<=', '2015-07-11');
$q->where('Available', '=', 'Yes');
})
->get();
Updated
Have you looked into whereBetween.
$query = Property::whereHas('Week', function($q) use ($arrive)
{
$q->whereBetween('WeekDate', '2015-07-04', '2015-07-11');
$q->where('Available', '=', 'Yes');
})
->get();

Laravel 4: Adding where clause to a join condition

It says in the laravel docs that it is possible to add where clause on a join, but whenever I try in my code using the where clause, I get the error: Call to undefined method Illuminate\Database\Query\JoinClause::where(). Anyone knows how to add where clause in a join clause?
Laravel Website Example:
DB::table('users')
->join('contacts', function($join)
{
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();
Code I'm trying to implement:
DB::table('users')
->join('contacts', function($join)
{
$current_date = date('Y-m-d');
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.effective_date', '>=', $current_date);
})
->get();
if you want add more condition on a join add more $join->on or $join->orOn.
if you want to add a condition to your first select, add it outside join function.
DB::table('users')
->join('contacts', function($join)
{
$date = date('Y-m-d');
$join->on('users.id', '=', 'contacts.user_id');
})
->where('contacts.effective_date', '>=', $date);
->get();
Updated
In Laravel 4.0 which I think you use, you can't use where inside your join closure, but since Laravel 4.1 and above you can have where conditions after your join condition. I couldn't find documentation for Laravel 4.1 but this is the #join documentation for L4.2 and above
Please Check Below Answer
DB::table('users')
->join('contacts', function($join)
{
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();
Try This solution
DB::table('users')
->join('contacts', function($join)
{
$current_date = date('Y-m-d');
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.effective_date', '>', $current_date)
->where('contacts.effective_date', '=', $current_date);
})
->get();
$current_date = date('Y-m-d');
DB::table('users')
->join('contacts', function($join) use ($current_date)
{
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.effective_date', '>=', $current_date);
})
->get();
You are calling $current_date but you decarle $date
DB::table('users')
->join('contacts', function($join)
{
$date = date('Y-m-d');
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.effective_date', '>=', $date);
})
->get();
I don't know if this solve the problem, try it ;)
You are sure that you are working with laravel 4.1? I think you are using laravel 4.0 instead of 4.1. Look in your composer.json file.
Add this just before the get() function call
->where('contacts.effective_date', '=', $current_date);
$users = DB::table('users')
->join('contacts', 'users.id', '=','contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')->get();
https://laravel.com/docs/5.6/queries please check this link

Categories