Laravel Eloquent Count multip - php

I currently have:
$emails = Email::select('username', DB::raw('count(*) as total'))
->groupBy('username')
->get();
Returning:
{'username' => 'example', 'total'=>'120' }
What I trying to do is to also get a count of a certain row value, where row value is equal to 1, to obtain:
{'username' => 'example', 'total'=>'120', 'sent' => '23' }
Like a :
DB::raw('count(sentitems) as sent WHERE sentitems = 1')
but of course it won't work this way .

If I understand you correctly, you mean something like this:
$emails = Email::select('username', DB::raw('count(*) as total'), DB::raw('count(case sentitems when 1 then 1 else null end) as sent')))
->groupBy('username')
->get();

What can the row value be if it isn't 1? If the only possible values are 0 and 1, you can simply use sum(sentitems). If other values are possible, you do sum(if(sentitems = 1, 1, 0))

Related

Fast query to load specific data column

I have this output format for kits result counting:
$out = array(
'in progress' => 0,
're-testing' => 0,
'rejected' => 0,
'negative' => 0,
'positive' => 0,
'inconclusive' => 0,
'failed' => 0,
'tested' => 0,
'available' => 0,
'total' => 0
);
I implemented a loop to query in the kits and then check for corrispondence in result value, like that:
$kits = Kit::where('customerId', Auth::id())->get();
foreach ($kits as $kit) {
if($kit->result !== '' && isset($out[$kit->result])){
++$out[$kit->result];
++$out['tested'];
}
if($kit->status == 'accepted' && !$kit->result){
++$out['in progress'];
}
++$out['total'];
}
unfortunately this solution is very slow. Do you have any suggestions for how to do that? thanks.
EDIT: Is slow because there are too many items.
First you are querying with a condition customerId, so add an index to customerId field will improve query performance a lot.
Then you don't have to count the total, you can use count().
$out['total'] = Kit::where('customerId', auth()->id())->count();
The part where you count the group of results ++$out[$kit->result]; looks like can be done with groupBy()
$kits = Kit::where('customerId', auth()->id())
->groupBy('result')
->select('result', DB::raw('COUNT(*) as no'))
->get();
Then for each result that you want to count, you can look up with firstWhere().
$out['positive'] = $kits->firstWhere('result', 'positive')->no;
$out['negative'] = $kits->firstWhere('result', 'negative')->no;
...
$out['tested'] is just the sum of all count.
$out['tested'] = $out['positive'] + $out['negative'] +...
And need another query for $out['in progress']
$out['in progress'] = Kit::where('customerId', auth()->id())
->where('status', 'accepted')
->whereNotNull('result')
->where('result', '!=', '')
->count();

How to pass value from database in laravel

How can I pass the value of lead_id to my attendance table?
Here is the code from my controller
$scores = Score::with('lead','subject')->get()->groupBy('lead_id');
I want to pass $scores here:
$atnds = DB::table('attendances')
->select(DB::raw('count(*) as total, status'))
->where('status', '=', 'P')
->whereBetween('days', [$from,$to])
->groupBy('status')
**->where('lead_id','=',$scores)**
->get();
Both table Score and Attendance has lead_id is it possible to connect them? i want to perform total base on the lead_id from score table is equal to attendance table. with my code i'm getting this empty array
try this:
$scores = Score::with('lead','subject')->get();
$atnds = DB::table('attendances')
->select(DB::raw('count(*) as total, status'))
->where('status', '=', 'P')
->whereBetween('days', [$from,$to])
->groupBy('status')
->whereIn('lead_id', array_column($scores->toArray(), 'lead_id'))
->get();
where condition in eloquent expects a string/integer value to be pased and not a collection as you are trying to pass it.
After you get the results from this query:
they should be grouped by keys like:
$scores = Score::with('lead','subject')->get()->groupBy('lead_id');
Collection{
1 => Collection{somedata},
2 => Collection{somedata},
}
So i pressume you need only the keys from this collection:
$atnds = DB::table('attendances')
->select(DB::raw('count(*) as total, status'))
->where('status', '=', 'P')
->whereBetween('days', [$from,$to])
->groupBy('status')
->whereIn('lead_id',$scores->pluck('lead_id')->toArray())
->get();
this is the result of DD$scores
"id" => 62
"subject_id" => 4
"lead_id" => 5
"uuid" => "36c850d0-9ec9-11e8-85e1-cdb65cbc1965"
"created_at" => "2018-08-13 07:19:27"
"updated_at" => "2018-08-13 07:19:27"
]
the total is not there

how to select count with a difference condition in laravel

I have this database structure
table tools table details
----------- -------------
id * id *
name balance_shoot
tool_id
I need to get count of tools that has balance_shoot in tool_details that is lesser than or equal zero (danger) and more than a zero (save). something like :
[
danger_count => 0,
save_count => 5
];
I already achieve this:
public function index(Request $request){
$trans_date = date('Y-m-d');
$tools = Tool::select('id')
->whereHas(
'details' , function ($query) use ($trans_date){
$query->where('trans_date', $trans_date );
}
)
/*->with([
'details' => function ($query) use ($trans_date){
$query->where('trans_date', $trans_date );
}
])*/
->withCount([
'details as danger' => function ($query) use ($trans_date){
$query->where('trans_date', $trans_date )->where('balance_shoot', '<=', 0 );
},
'details as save' => function ($query) use ($trans_date){
$query->where('trans_date', $trans_date )
->where('balance_shoot', '>', 0 );
},
]);
return $tools->get();
}
And it's return this :
"tools": [
{
"id": 101,
"danger_count": "0",
"save_count": "1"
},
{
"id": 102,
"danger_count": "0",
"save_count": "1"
}
];
How can I get that data structure but in one single result return ??
SQL Query
select count(*) total, sum(case when balance_shoot < '0' then 1 else 0 end) danger, sum(case when balance_shoot > '0' then 1 else 0 end) safe from tool_dtl group by tool_id
In Laravel you can try this
<?php
$toolDtl = Detail::select(
array(
DB::raw('COUNT(*) as total'),
DB::raw("SUM(CASE
WHEN balance_shoot < '0' THEN 1 ELSE 0 END) AS danger"),
DB::raw("SUM(CASE
WHEN balance_shoot > '0' THEN 1 ELSE 0 END) AS save")
)
)
->groupBy('tool_id')
->orderBy('id', 'asc')->get();
?>
We can count directly using conditional SUM
Detail::select([
DB::raw('COUNT(*) as total'),
DB::raw("SUM(balance_shoot < '0') AS danger"),
DB::raw("SUM(balance_shoot > '0') AS save")
])

In yii2 query builder how to use in operator with where clause

I did not find any example of yii2 query builder yii\db\Query using in operator with where clause. for the time being I am using it this way
$result = (new \yii\db\Query)
->select('*')
->from('customer c')
->where('c.status in (' . implode(',', [0,1]) . ')')->all();
But there must be a better way of doing this. Thanks in advance
$result = (new \yii\db\Query)
->select('*')
->from('customer c')
->where(['c.status' => [0, 1]])->all();
In the yii\db\QueryInterface::where() API:
The $condition specified as an array can be in one of the following two formats:
hash format: ['column1' => value1, 'column2' => value2, ...]
operator format: [operator, operand1, operand2, ...]
... In case when a value is an array, an IN expression will be generated.
['id' => [1, 2, 3], 'status' => 2] generates (id IN (1, 2, 3)) AND (status = 2).

Why laravel query doesn't return right result?

I have this code in laravel to get the products that will run out soon.
$productos = DB::table('productos')
->where('producto_minimo', '>=', 'producto_cantidad')
->get();
And what I get is the following result
which is not the right result. While in MySql I get the right results whith this query SELECT * FROM productos where producto_minimo >= producto_cantidad;
Update
The query log - DB::getQueryLog() - shows this
2 =>
array (size=3)
'query' => string 'select * from `productos` where `producto_minimo` >= ?' (length=54)
'bindings' =>
array (size=1)
0 => string 'producto_cantidad' (length=17)
'time' => float 1
I assume you've got to use the whereRaw method:
$productos = DB::table('productos')
->whereRaw('producto_minimo >= producto_cantidad')
->get();
Your query will compare the value in the column producto_minimo with the string 'producto_cantidad'
Have a look at Eloquents documentation of advanced wheres:
DB::table('users')
->whereExists(function($query)
{
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
The query above will produce the following SQL:
select * from users
where exists (
select 1 from orders where orders.user_id = users.id
)

Categories