How to fix whereNotExists and where query builder laravel - php

I try to combine whereNotExists and where, if you use it simultaneously it will and if you try one of them you can
$query = DB::table('tabel_produk')->where('kode_customer',$cust)->whereNotExists(function($query){
$query->select(DB::raw(1))->from('tabel_detail_realisasi')->whereRaw('tabel_detail_realisasi.barcode = tabel_produk.barcode');
})->distinct()->orderBy('barcode','asc') ->get();
Pleae help me with this

I don't have your DB schema so I've tried something similar with a local DB I have and it seems to be working fine. See my example below. Could you please replace my query with yours and see what's output by the query logger?
DB::flushQueryLog();
DB::enableQueryLog();
$results = DB::table('product_templates')
//Non deleted products
->where('deleted', '=', '0')
//
->whereNotExists(function ($query) {
//Where the category is not 'General'
$query
->select(DB::raw(1))
->from('product_categories')
->whereRaw('product_categories.id = product_templates.category_id')
->where('product_categories.name', 'General');
})
->distinct()
->orderBy('name', 'asc')->get();
DB::disableQueryLog();
$queryLog = DB::getQueryLog();
logger("Query results", compact('results', 'queryLog'));

Related

laravel 6 search query with multiple conditions

I have a search form with four fields of customer email, vendor name, status, and fromdate, todate,. My search filter is not working properly. I want if someone searches a lead with vendor name and status Active then it shows only leads of that vendor with status active status but here it shows a leads with both Accept or Reject also my date filter is not working so please help me. Please guide me
my controller code is
public function search(Request $request){
$users = DB::table('users')->where('is_admin', Null)->get();
$customer_email = $request->input('customer_email');
$vendor_id = $request->input('vendor_id');
$status = $request->input('lead_status');
$leads = DB::table('leads')
->leftJoin('users', 'leads.vendor_id', '=', 'users.id')
->select('leads.*', 'users.name')
->where('vendor_id', $vendor_id)
->orWhere('customer_email', $customer_email)
->orWhere('lead_status', $status)
->orWhere('leads.created_at', array($request->start_date, $request->end_date))
->orderBy('leads.created_at', 'DESC')->get();
//dd($leads);
return view('admin.view-leads', compact('leads'), compact('users'));
}
please help.
Thanks in advance
query image
That's a pretty simple thing. Just follow the code below.
To get the users where is_admin is null.
$users = DB::table('users')->whereIsNull('is_admin')->get();
To check if you are submitting a value for any filter.
if($request->filled('name_of_filter_input')){ //code goes here }
So your query to filter records will go like.
$query = DB::table('leads')->query();
$query->leftJoin('users', 'leads.vendor_id', '=', 'users.id');
$query->select('leads.*', 'users.name');
if($request->filled('vendor_id')) {
$query->where('vendor_id', $request->input('vendor_id'));
}
if($request->filled('customer_email')) {
$query->where('customer_email', $request->input('customer_email'));
}
if($request->filled('lead_status')) {
$query->orWhere('lead_status', $request->input('lead_status'));
}
if($request->filled('start_date') && $request->filled('end_date')) {
$query->whereBetween(DB::raw('date(leads.created_at)'), [$request->input('start_date'), $request->input('end_date')]);
}
$leads = $query->orderBy('leads.id', 'DESC')->get();
Further you can replace DB::table('table_name') syntax with respective model classes in case query() seems to be undefined function.
Wrap leads.created_at with date() function and ensure your date filter(s) has date in yyyy-mm-dd format if the created_at column is of type timestamp.
you should write your query like as below
$leads = DB::table('leads')
->leftJoin('users', 'leads.vendor_id', '=', 'users.id')
->select('leads.*', 'users.name')
->where('vendor_id', $vendor_id)
->when($customer_email, function($q,$customer_email){
$q->where('customer_email', $customer_email);
})
->when($status, function($q,$status){
$q->where('lead_status', $status);
})
->where(function($q) use($request){
if(isset($request->start_date) && isset($request->end_date)){
$fromDate = date('Y-m-d H:i:s',strtotime($request->start_date));
$toDate= date('Y-m-d H:i:s',strtotime($request->end_date));
$q->where('leads.created_at', '>=', $fromDate)
->where('leads.created_at', '<=', $toDate);
}
})
->orderBy('leads.created_at', 'DESC')->get();
I updated my answer please look into it

Trending query Laravel

Right now I have a subquery to get the count of payments for the current month and then getting the 4 products with the highest payment_count. This query works fine but I'm wondering if there's a more simple way to do the same since its getting difficult to read.
$latestPayments = DB::table('payments')
->select('product_id', DB::raw('COUNT(*) as payments_count'))
->whereMonth('created_at', Carbon::now()->month)
->groupBy('product_id');
$trendingProducts = DB::table('products')
->joinSub($latestPayments, 'latest_payments', function ($join) {
$join->on('products.id', '=', 'latest_payments.product_id');
})->orderBy('payments_count', 'DESC')->take(4)->get();
This did it!
$trendingProducts = Product::withCount(['payments' => function($query) {
$query->whereMonth('created_at', Carbon::now()->month);
}])->orderBy('payments_count', 'DESC')->take(4)->get();
If you are using eloquent query with relational database you can do like this:
$latestPaymentWithTrendingProduct = App\Payment::with(['products', function($product) {
$product->orderBy('payments_count', 'DESC')->take(4);
}])->whereMonth('created_at', date('m'))->get()->groupBy('product_id');
This will lessen the code but still do the same thing.

How to split up an Eloquent model query

I'm trying to break up an Eloquent query like this
$query = new Product;
if (!empty($req->query['id'])) {
$query->where('id', '=', '1');
}
$products = $query->get();
The result above gives me all products in the database. This however, does in fact work.
$products = Product::where('id', '=', '1')->get();
Is there a way to do this?
In Laravel 4 you need to append your query parameters to your query variable. In Laravel 3, it would work like you're doing.
This is what you need to do (I'm unsure if it will work with new Product tho):
$query = new Product;
if (!empty($req->query['id'])) {
$query = $query->where('id', '=', '1');
}
$products = $query->get();
Your code does not make sense. If you make a new Product - then it will never have an ID associated with it - so your if (!empty($req->query['id'])) will always be false.
Are you just trying to get a specific product idea?
$products = Product::find(1);
is the same as
$products = Product::where('id', '=', '1')->get();

laravel using query builder without chaining

I have a query builder that works:
$article = Page::where('slug', '=', $slug)
->where('hide', '=', $hidden)
->first();
But I want to only add the second where statement if hidden is equal to 1. I've tried the code below which shows the logic of what I'm trying to do, but it doesn't work.
$article = Page::where('slug', '=', $slug);
if ($hidden == 1) {
$article->where('hide', '=', 1);
}
$article->first();
I'm using Laravel 4, but I think the question still stands with Laravel 3.
Yeah there's a little "gotcha" with Eloquent and the query builder. Try the code below ;)
$query = Page::where('slug', '=', $slug);
if ($hidden == 1) {
$query = $query->where('hide', '=', 1);
}
$article = $query->first();
Note the assigning of $query within the conditional. This is becuase the first where (statically called) returns a different object to the query object within the conditional. One way to get around this, I believe due to a recent commit, is like so:
$query = Page::where('slug', '=', $slug)->query();
This will return the query object and you can do what you want as per normal (Instead of re-assigning $query).
Hope that helps.

Query building using Kohana Query Builder

If I got this:
$result =
DB::select(
'orders.date_created'
)
->from('orders')
->execute()->as_array();
For normal, dsiplaying all orders date_created. Now I can filter by user, doing this ?user_id=112
This will make me having this:
if(isset($get['user_id']))
{
$result =
DB::select(
'orders.date_created'
)
->from('orders')
->where('user_id', '=', $get['user_id'])
->execute()->as_array();
}else{
$result =
DB::select(
'orders.date_created'
)
->from('orders')
->execute()->as_array();
}
Although this is no problem for me have this, but this get to be real much ugly code when I have 4 params to filter out from(4 where statements) e.g ?user_id=112&quantity=2&...
Can I somehow make a inline if/action statement, which would grab all user_ids if there's nothing in $get['user_id'] ?
So I can end up having only this:
$result =
DB::select(
'orders.date_created'
)
->from('orders')
->where('user_id', '=', (isset($get['user_id']) ? $get['user_id'] : 'GRAB ALL!'))
->execute()->as_array();
or is there another, even better way to do this?
Tried looking in Kohana docs if there's some ->if()->where()->exitif().. (just some imagination of how it could work)
You can modify Query object before executing:
$query = DB::select()->from(...);
if (isset($get['user_id'])) {
$query->where('user_id', '=', intval($get['user_id']));
}
if (isset($get['quantity'])) {
$query->where('quantity', '=', floatval($get['quantity']));
}
$result = $query->execute()->as_array();

Categories