Laravel - Display Active and Inactive on the same page - laravel

I have a table with these fields: name and plan_status.
The plan_status can be 0 or 1. 1 is active, 0 is inactive. I want to display |name|active|inactive|.
I am only able to run a query that displays either active and inactive ones.
Model:
protected $fillable = [
'name', 'plan_status'
];
Controller:
$actives = DB::table('users')
->select(DB::raw('count(*) as active'))
->where('plan_status', 1)
I want the query to display both names, active and inactive: |name|active|inactive|.

Here is the query which will provide you exact result which you want
$actives = DB::table('users')
->selectRaw('
name,
IF((plan_status = 1), "Yes", "No") as active,
IF((plan_status = 0), "Yes", "No") as inactive,
IF((plan_status = 2), "Yes", "No") as undefined
')
->get()
Try this and check. I think this will solve your problem.
Edited
To get count of status wise
$actives = DB::table('users')
->selectRaw('
name,
IF((plan_status = 1), COUNT(*), "0") as active,
IF((plan_status = 0), COUNT(*), "0") as inactive,
IF((plan_status = 2), COUNT(*), "0") as undefined
')
->groupBy('plan_status')
->get()
like this
Try both the solutions.

try this one using group by
DB::table('users')
->select('name',
DB::raw('IF((plan_status = 1), count(*), 0) as active'),
DB::raw('IF((plan_status = 0), count(*), 0) as inactive'),
)->groupBy('plan_status')->get()

Related

How to take count based on different where conditions in laravel?

I am trying to count tickets based on different where conditions . For which I am using four different queries but same model. Can I do that in one query?
$openTickets = Ticket::where('status',1)->count();
$pending = Ticket::where('status',2)->count();
$unAssigned = Ticket::where('agent_id',null)->count();
$unResolved = Ticket::whereNotIn('status',[3,4])->count();
Ticket::selectRaw('COUNT(CASE WHEN status = 1 THEN 1 END) AS open_tickets')
->selectRaw('COUNT(CASE WHEN status = 2 THEN 1 END) AS pending_tickets')
->selectRaw('COUNT(CASE WHEN agent_id IS NULL THEN 1 END) AS unassigned_tickets')
->selectRaw('COUNT(CASE WHEN status NOT IN (3,4) THEN 1 END) AS unresolved_tickets')
->first();
You can of course resolve the multiple queries with this query. We can use conditional cases and count.
You can sum up conditionals but will need lots of raw parts in your query:
$result = DB::table('tickets')->whereIn('status', [1,2])->orWhereNull('agent_id')->orWhereNotIn('status', [3,4]) // This is to filter out the things we don't care about
->select([
DB::raw('SUM(IF(status = 1, 1,0)) as countOpen'),
DB::raw('SUM(IF(status = 2, 1,0)) as countPending'),
DB::raw('SUM(IF(agent_id IS NULL, 1,0)) as countUnassigned'),
DB::raw('SUM(IF(status NOT IN (3,4), 1,0)) as countUnresolved'),
])->first()
$openTickets = $result->countOpen;
$pending = $result->countPending;
$unAssigned = $result->countUnassigned;
$unResolved = $result->countUnresolved;

Laravel find difference of sum of same column with difference condition

I have a table with different types of data. I want to find
sum(typeA) - sum(typeB)
Type A = whereIn('type', ['CreditNote','ReceiptVoucher'])
Type B = ->whereIn('type', ['DebitNote','PaymentVoucher'])
This is the query I came up with, but it isn't working. What am I missing?
Transaction::where('contact_id',$this->contact->id)->where('date', '<', $from)
->where(function ($query) {
$query
->whereIn('type', ['CreditNote','ReceiptVoucher'])
->selectRaw("SUM(amount) as in");
})
->Where(function ($query) {
$query
->whereIn('type', ['DebitNote','PaymentVoucher'])
->selectRaw("SUM(amount) as out");
})
->selectRaw("COALESCE(SUM(in),0) - COALESCE(SUM(out),0) as amount")
->groupBy('contact_id')
->get();
If I can't find a difference like this, I could also just get the two sums and I can subtract them later.
You could use raw query to get this, you just need to specify the WHERE statement for date and contact_id, then for the SUM statement, put the type conditions inside the IF statement like this:
SELECT
SUM(// TYPE CONDITIONS FOR IN, Quantity, 0)) - SUM(IF(// TYPE CONDITIONS FOR IN, Quantity, 0)) as total
FROM x
WHERE ...
GROUP BY ...;
After you've tried the raw query, use DB::raw to execute it.
Note: somehow in and out that you used for the aliases were SQL's keywords, so change it to inQty and outQty or whatever.
SELECT SUM(IF(OrderDetailId <= 5, Quantity, 0)) as inQty, SUM(IF(OrderDetailId > 5 AND OrderDetailId <= 10, Quantity, 0)) as outQty, SUM(IF(OrderDetailId <= 5, Quantity, 0)) - SUM(IF(OrderDetailId > 5 AND OrderDetailId <= 10, Quantity, 0)) as total FROM OrderDetails;

Laravel Query Builder and Eloquent query builder add an odd phrase when I try to build the query on the fly?

I am attempting to build a query on the fly depending upon what is entered in a form. When I do so, I check what the sql statement is in the Console. I have OR and AND contitions, so I use a call back to build the query. the SQL statement that results is:
select `id`, `activity_name`, `activity_name_web`, `year`, `season`, `sex`,
`active_on_web`, `begin_active_on_web`, `end_active_on_web`, `begin_age`,
`end_age`, `begin_date`, `end_date` from `activities` where (season='fall'
OR season='summer' is null) order by `begin_date` desc, `activity_name` asc
limit 25 offset 0 []
notice the words "is null". I can't determine how this phrase is being added.
The Code:
$qry_where = "1";
$arry_Season = array();
if($this->a_fall)
$arry_Season[] = "LOWER(`season`)='fall'";
if($this->a_spring)
$arry_Season[] = "LOWER(`season`)='spring'";
if($this->a_summer)
$arry_Season[] = "LOWER(`season`)='summer'";
if($this->a_winter)
$arry_Season[] = "LOWER(`season`)='winter'";
if(count($arry_Season)>0) {
$qry_where = $arry_Season[0];
if(count($arry_Season)>1){
array_shift($arry_Season);
foreach($arry_Season as $season){
$qry_where .= " OR " . $season;
}
}
}
$activities = Activity::select('id','activity_name','activity_name_web','year','season', 'sex', 'active_on_web',
'begin_active_on_web', 'end_active_on_web', 'begin_age', 'end_age', 'begin_date','end_date')
->where(function($query) use ($qry_where) {
if($qry_where == "1")
$query->where('id','>',0);
else {
$query->where(DB::raw($qry_where));
}
})
->orderBy('begin_date','desc')->orderBy('activity_name','asc')
->paginate(25);
So, if the users checks the box labelled "fall", I add it to the query builder.
so - Where is the phrase "is null" coming from.
select `id`, `activity_name`, `activity_name_web`, `year`, `season`, `sex`,
`active_on_web`,`begin_active_on_web`, `end_active_on_web`, `begin_age`,
`end_age`, `begin_date`, `end_date` from `activities`
where (season='fall' OR season='summer' is null)
order by `begin_date` desc, `activity_name` asc limit 25 offset 0 []
btw, say I check fall and summer, then I ddd($qry_where) just before I build the query, I get this:
"LOWER(`season`)='fall' OR LOWER(`season`)='summer'"
I also need to mention that I am using a livewire component.
thanks for the help in advance.
#apokryfos thank you for your quick answer. It was driving me crazy. It seems when I passed a variable into the ->where(DB::raw()), it evaluated the variable too late for the ->when() to see that the variable contained a comparison?
In any case, I tweeked the solution that #apokryfos a bit and came up with the following:
$activities = Activity::select('id','activity_name','activity_name_web','year','season', 'sex', 'active_on_web',
'begin_active_on_web', 'end_active_on_web', 'begin_age', 'end_age', 'begin_date','end_date',
'cost_member','cost_non_member')
->when(count($seasons) > 0, function($query) use ($seasons) {
$query->whereIn('season', $seasons);
})
->orderBy('begin_date','desc')->orderBy('activity_name','asc')
->paginate($this->items_on_page);
the ->whereIn() could not process the "DB::raw('LOWER(season)', $seasons)" as suggested. If i want to make sure that the data in the [activities].[season] column, I will either have to make sure the seasons are input into the table in lower case, or do a ->select(DB:raw('LOWER(season)') in the SQL statement. I like the first option.
thank you again for your input apokryfos
You did a where(<raw query>) which defaults to do a WHERE <raw query> is not NULL since WHERE assumes a comparison. Here's what I think is a more concise version of your query:
$seasons = array_filter([
$this->a_spring ? 'spring' : null,
$this->a_summer ? 'summer' : null,
$this->a_fall ? 'fall' : null
$this->a_winter ? 'winter' : null
]);
$activities = Activity::select('id','activity_name','activity_name_web','year','season', 'sex', 'active_on_web',
'begin_active_on_web', 'end_active_on_web', 'begin_age', 'end_age', 'begin_date','end_date')
->when(count($seasons) > 0, function($query) use ($seasons) {
$query->whereIn(DB::raw('LOWER(season)'), $seasons);
})->when(count($seasons) == 0, function ($query) {
$query->where('id', > 0); // Not sure you need this part
})
->orderBy('begin_date','desc')->orderBy('activity_name','asc')
->paginate(25);

Reproduce in eloquent

I am not able to reproduce this query in eloquent.
How could I have made a query without eloquent?
select * from points where operator = 2 and (month(date) = '1' and day(date) >= 25 or month(date) = '2' and day(date) <= 24)
You may use DB facade for this purpose..
$query = "select * from points where operator = :operator and (month(date) = :monthDate and day(date) >= :dayDate or month(date) = :monthDate2 and day(date) <= :dayDate2)"
$points = DB::select($query,[
"operator" => 2,
"monthDate" => 1,
"dayDate" => 25,
"monthDate2" => 2,
"dayDate2" => 24
])
Considering you have Point model for points table, below eloquent query should work :
<?php
$points = Point::where('operator', 2)->where(function($q){
return $q->whereMonth('date', '=', 1)->whereDay('date', '>=', 25);
})->orWhere(function($q){
return $q->whereMonth('date', '=', 2)->whereDay('date', '<=', 24);
})->get();

The "Eloquent way": If no model found, drop where constraint

Is there a more "eloquent way" to code this behavior?
$this->template = Template::where('template_type_id', 1)
->where('locale', 'en')
->first() ?? Template::where('template_type_id', 1)
->first();
So I first want to check if there is a model with the ->where('locale', 'en') condition, if not I want to drop this where condition.
You could use an ORDER BY clause to favour a template with a locale equal to en, and then select only the first result.
$template = Template::where('template_type_id', 1)
->orderByRaw("IF(locale = 'en', 1, 0) DESC")
->first();

Resources