SQL: Query returns 1 using count - php

I have a query in PHP(MySQL). I am fetching records from a table and returning them to a datatable.
The problem is it always returns 1 when I use count() with the query.
However, if I count the elements of the array, then the result is as expected. It returns all 8 records.
Following is my code:
public function job_order_detail_del($arr=array()) {
$count = 0;
$start = isset($arr['start'])?$arr['start']:0;
$length = isset($arr['length'])?$arr['length']:0;
$search = isset($arr['search'])?$arr['search']:'';
$orderBy = isset($arr['orderBy'])?$arr['orderBy']:'';
$orderDir = isset($arr['orderDir'])?$arr['orderDir']:'';
$aufnr = isset($arr['aufnr'])?$arr['aufnr']:0;
$aufpl = isset($arr['aufpl'])?$arr['aufpl']:0;
$type = isset($arr['type'])?$arr['type']:'';
$whr = array('h.stats' => '', 'h.bukrs' => Session::get('company'), 'h.delstats' => '');
if ($aufnr > 0)
$whr['a.aufnr'] = $aufnr;
if ($aufpl > 0)
$whr['a.aufpl'] = $aufpl;
$a = DB::table('zpp_afpo_h as h')
->leftjoin('zpp_afpo as a ', function($join) {
$join->on('a.aufnr', '=', 'h.aufnr')
->where('a.bukrs', '=', Session::get('company'))
->where('a.stats', '=', '');
})
->leftjoin('zpp_afvc as b ', function($join) {
$join->on('a.aufnr', '=', 'b.aufnr')
->on('a.aufpl', '=', 'b.aufpl')
->where('b.bukrs', '=', Session::get('company'))
->where('b.stats', '=', '');
})
->leftjoin('zpp_afru as c ', function($join) use($type) {
$join->on('c.aufnr', '=', 'b.aufnr')
->on('c.rueck', '=', 'b.rueck');
})
->where('c.type', '=', $type)
->where('c.bukrs', '=', Session::get('company'))
->where('c.stats', '=', '')
->where('c.delstats', '=', '')
->select('h.idat2', 'a.matnr', 'b.arbpl', 'a.gamng as total', 'b.rueck', 'h.priority', 'b.vornr', 'b.prev_startper', 'b.scrap', 'h.dispatch_date', 'h.order_start_dt', 'h.requirement_dt', 'h.ktxt', 'c.rmzhl', 'c.budat', 'c.aufnr', 'c.rework_lmnga', DB::raw('sum(c.lmnga) as sum_cnfrm'));
if ($aufnr == '') {
$a->where('h.idat2', '=', '0000:00:00');
}
$a->where($whr)
->groupby('b.rueck')
->groupby('c.rmzhl')
->groupby('c.counter');
if($orderBy!=''){
$a->orderBy($orderBy,$orderDir);
}
if($search!=''){
$dt_srch = implode('-',array_reverse(explode('-',$search)));
$a->where(function($query) use ($search,$dt_srch){
$query->where('c.aufnr','LIKE','%'.$search.'%')
->orWhere('a.matnr','LIKE','%'.$search.'%')
->orWhere('c.budat','LIKE','%'.$dt_srch.'%')
->orWhere('b.arbpl','LIKE','%'.$search.'%')
->orWhere('a.gamng','LIKE','%'.$search.'%');
});
}
if($length>0){
$get_rec = $a->skip($start)->take($length)->get();
}else{
$get_rec = $a->get();
$count = count($get_rec);
// $count = $a->count(); //Problem is here
return $count;
}
$arr = array();
foreach($get_rec as $l){
if($length>0 || Input::get('open') == 1 || Input::get('open') == 2){
$arr = DB::table('maras')
->where('matnr','=',$l->matnr)
->where('bukrs','=',Session::get('company'))
->where('stats','=','')
->where('delstats','=','')
->select(DB::raw('GROUP_CONCAT(distinct(matnr)) as mat'),DB::raw('GROUP_CONCAT(distinct(mdesc)) as mat_desc'))
->groupby('matnr')
->first();
$l->matnr = $arr->mat;
$l->mat_desc = $arr->mat_desc;
}
}
return $get_rec;
}
Please let me know the problem. Thanks in advance.

You are using count on groupBy element and count is returning only the grouped count. That's why it is returning only single row or 1. You could count the returned collections in this case like-
$count = $get_rec->count();

Related

I need help to turn some raw SQL into Eloquent code

As the title says, I'm having trouble turning my SQL code into Eloquent.
Here's the raw SQL:
select * from `students`
where (
select status_student.id from `status_student`
WHERE
status_student.id = (SELECT MAX(status_student.id) from `status_student`
WHERE
status_student.student_id = students.id)
AND
status_student.status_id = 6
)
IS NOT NULL;
and here's the code so far:
$status = $this->request->get('status');
if ($status !== "0") {
dd($query = Student::where(function($q) use($status){
$q->where('status_student.id', function($q2) use ($status) {
$q2->selectRaw('MAX(status_student.id)')
->where('status_student.student_id', '=', 'students.id')
->where('status_student.status_id', '=', $status);
});
})->toSql());
}
which translates into SQL:
"select * from `students` where (`status_student`.`id` = (select MAX(status_student.id) where `status_student`.`student_id` = ? and `status_student`.`status_id` = ?))
so it's not working properly yet.
I'm having trouble introducing that IS NOT NULL clause and doing
select status_student.id from 'status_student'
instead of just
status_student.id =
How should I modify my code to get the desired SQL?
Thanks.
$status = request()->get('status');
if ($status !== "0") {
dd($query = Student::where(function($q) use($status){
$q->where([['status_student.id' => function($q2) use ($status) {
$q2->selectRaw('MAX(status_student.id)')
->where('status_student.student_id', '=', 'students.id')
->where('status_student.status_id', '=', $status);
}],
['status_student.id', '<>', null]
]);
})->toSql());
}
Generated SQL query:
SELECT *
FROM `students`
WHERE (((`status_student`.`student_id` = ?
AND `status_student`.`status_id` IS NULL)
AND `status_student`.`id` IS NOT NULL))
Not sure if I understanded you correctly but I assume you just didn't get the syntax right
try this one:
$status = $this->request->get('status');
if ($status !== "0") {
// log the queries:
\DB::enableQueryLog();
$query = Student::with([
'statusStudent' => function($q1) use($status) {
$q1->where('status_student.id', function($q2) use ($status) {
$q2->selectRaw('MAX(status_student.id)')
->where('status_student.student_id', '=', 'students.id')
->where('status_student.status_id', '=', $status);
});
}
])
->get();
$pureQuery = \DB::getQueryLog();
dd($pureQuery);
}
If you would like to join in eloquent, you must use with() or load() to do that.

How to Assign or store Model's table name into variable in laravel (this is for filter functionality)?

How to Assign or store Model's table name into a variable in laravel (this is for filter functionality)?
$query = new LiveClasses;
if (request('language')) {
// die("333");
$query->where('language_used', '=', request('language'));
}
if (request('start') && request('last')) {
// die("333");
$first = 'sub_price_1 >= ' . request('start');
$second = 'sub_price_1 <= ' . request('last');
$query->whereRaw($first)->whereRaw($second);
}
if (request('rating')) {
// die("&rating=5&start=150&last=1264");
$query
->leftJoin('reviews', 'reviews.reviewable_id', '=', 'live_classes.id')
->Where('rating', request('rating'))
->Where('reviewable_type', '=', 'App\Models\LiveClasses');
// $courses = Review::where('rating', request('rating'))
// ->leftJoin('live_classes', 'reviews.reviewable_id', '=', 'live_classes.id')
}
$courses = $query->paginate(9);
To get the name of model table use ->getTable() eloquent method.
To get the morphable class name (type) use ->getMorphClass() eloquent method.
$query = new LiveClasses;
if (request('language')) {
$query->where('language_used', '=', request('language'));
}
if (request('start') && request('last')) {
$first = 'sub_price_1 >= ' . request('start');
$second = 'sub_price_1 <= ' . request('last');
$query->whereRaw($first)->whereRaw($second);
}
if (request('rating')) {
$reviewTable = (new Review)->getTable();
$query
->leftJoin($reviewTable, reviewTable . '.reviewable_id', '=', $query->getTable() . '.id')
->where('rating', request('rating'))
->where('reviewable_type', '=', $query->getMorphClass());
}
$courses = $query->paginate(9);

Fetch posts that have a tag that the user has as well

In a Laravel app, I'm trying to implement a structure where posts are fetched that have one or more of the tags that the user has access to. I wrote the code below to do that:
$query = new Posts();
if (count(Auth::user()->tags) > 0) {
$query = $query->whereHas('tags', function ($q) {
$i = 0;
foreach (Auth::user()->tags as $tag) {
if ($i == 0) {
$q->where('title', '=', $tag->title);
} else {
$q->orWhere('title', '=', $tag->title);
}
$i++;
}
});
}
$posts = $query->where('isTemplate', true)->orderBy($key, $order)->paginate(15);
This works, but feels off. So I'm wondering if there's a better way to do this?
#user4992124, Will this help you.
$query = Posts::query()
->where('isTemplate', true)
->orderBy($key, $order);
if (Auth::user()->tags->isNotEmpty()) {
$tags = Auth::user()
->tags
->pluck('title')
->toArray();
$query = $query->whereIn('tags', $tags);
}
$posts = $query->paginate(15);

Get data whereBeetween two coloms

I'm using Laravel 5.5.
I have Table centrals with Model Centrals
and table like this
my Controller
$from = $request->year_from;
$to = $request->year_to;
$month_from = $request->month_from;
$month_to = $request->month_to;
$param = $request->get('parameters_id', []);
$search = Centrals::whereIn('parameters_id', $param)
->where('type', 'Monthly')
->where('year', $from)
->whereBetween('months_id', [$month_from, $month_to])
->orderBy('year')
->get();
now how i get data
example request:
$request->year_from = 2016;
$request->month_from = 1; /* 1 =Jan*/
$request->year_from = 2018;
$request->month_from = 3; /* 3 =Mar*/
The following should do the trick:
$search = Centrals::whereIn('parameters_id', $param)
->where('type', 'Monthly')
->where(function($q) use ($yearFrom, $monthFrom) {
$q->where('year', '>', $yearFrom);
$q->orWhere(function($q2) use ($yearFrom, $monthFrom) {
$q2->where('year', $yearFrom);
$q2->where('month', '>=', $monthFrom);
});
})
->where(function($q) use ($yearTo, $monthTo) {
$q->where('year', '<', $yearTo);
$q->orWhere(function($q2) use ($yearTo, $monthTo) {
$q2->where('year', $yearTo);
$q2->where('month', '<=', $monthTo);
});
})->get();

Laravel dynamic queries with premade string

How to insert strings as query in Laravel? I have to handle a dynamic value for "book formats" (such as "pdf", "epub", "physical", "") and this formats are separated by comma. Here is my code:
$formats_sql = '';
$format_filter_count = 0;
$format_filter = explode(',', $format_filter);
foreach ($format_filter as $format_filter_tmp) {
if ($format_filter_count == 0) {
$formats_sql .= "where('format', '=', '{$format_filter_tmp}')";
} else {
$formats_sql .= "->orWhere('format', '=', '{$format_filter_tmp}')";
}
$format_filter_count += 1;
}
if ($price_filter == 'paid') {
$books = Book::where('book_id', '=', $category_book->book_id)->$formats_sql->where('sell_price', '>', '0')->where('status', '=', '1')->get();
}
But makes this problem:
Undefined property: Illuminate\Database\Eloquent\Builder::$where('format', '=', 'pdf')->orWhere('format', '=', 'epub')
Your over complicating this. You should be using whereIn where you need to search for an array of values.
You whole code above can be condensed to:
if ($price_filter == 'paid') {
$formats = explode(',', $format_filter);
Book::where('book_id', $category_book->book_id)->whereIn('format', $formats)->where('sell_price', '>', '0')->where('status', '1')->get();
}

Categories