Using SUM in Laravel - mysql

I am a new Laravel learner and having difficulty to convert from sql
here is my sql
select sum(employee_income)
from employee
group by employee_id, employee_department
this query works when I test.
here is my simplified Laravel but it doesn't work.
DB::raw('(select sum(employee_income) from employee group by employee_id, employee_department)')
Can anybody see something wrong?

You shouldn't use DB::raw() unless you have to. Laravel has the Eloquent Query Builder, which provides an easy to type, Database-agnostic (works with all DBs) method of writing queries. This one should be pretty simple:
$sum = Employee::groupBy('employee_id')
->groupBy('employee_department')
->sum('employee_income');
// Or, if you don't have an `Employee.php` model
$sum = DB::table('employees')
->groupBy('employee_id')
->groupBy('employee_department')
->sum('employee_income');

Related

Count & GroupBy Function Laravel

I'm building some analytical stat graphs for an administrator dashboard using Laravel. I'm having a lot of fun. Though I'm having a bit of difficulty understanding how to utilize the SQL queries and GroupBy function to achieve some stuff.
End goal: retreive the count of users who were created and groupBy the week they registered.
So far I'm using this:
DB::table("users")
->select(DB::raw("COUNT(*) as count"))
->orderBy("created_at")
->groupBy(function ($query)
{
return \Carbon\Carbon::parse($query->created_at)->format("W");
})
->get();
I'm getting an error in Tinker (which is where I do a majority of my testing at the moment it's something like this:
PHP warning: strtolower() expects parameter 1 to be string, object given in
/Users/Ian/sites/bangerz-army/vendor/laravel/framework/src/Illuminate/Database/Grammar.php on line 58
I had gotten a similar query to work in PHP but for performance reasons I'd prefer to keep as much of the math in SQL as possible.
/ Laravel 5.5
Try using DB::raw() in your group by
DB::table("users")
->select(DB::raw("COUNT(*) as count, WEEK(created_at)"))
->orderBy(DB::raw('WEEK(created_at)'))
->groupBy(DB::raw('WEEK(created_at)'))
->get();

how to convert my MySql query in Laravel

i am little bit confused that how my query convert in laravel..
select users.username,users.photo, questions.*,
(Select count(*) from answers
where answers.q_id=questions.id) as aAccount from questions
INNER JOIN users ON users.id=questions.user_id
Use Raw query
These expressions will be injected into the query as strings, so be careful not to create any SQL injection points! To create a raw expression, you may use the DB::raw method
DB::table('questions')
->join('users', 'users.id', '=', 'questions.user_id')
->select('users.username','users.photo', 'questions.*',
DB::raw("
( Select count(*) from answers
where answers.q_id=questions.id
)as 'aAccount'")
->get();
I upvoted JYoThl answer as it's exactly how I'd breakdown this query into eloquent, though in instances where a portion of your Eloquent query becomes raw, I personally prefer keeping the entire sql raw. You can still inject variables into it if required.
In my experience, the amount of time spent normalizing a more complex query like this will be used when you go back to the code to re-read it.
Here's how you would pass your sql in it's raw format. I also like to convert the array into a collection, as collections offer a variety of methods. Hope this helps!
$questions = collect(DB::select( DB::raw("
select users.username,users.photo, questions.*,
(Select count(*) from answers where answers.q_id=questions.id) as aAccount
from questions
INNER JOIN users ON users.id=questions.user_id")
));
You would add variables into an array() area if you want to inject a variable. If you wanted to do that you would do something like this:
DB::select( DB::raw("select * from user where user = :user"), array('user' => $user))

Writing Query in laravel

Hello i'm new to laravel framework
i have a MySQL query .This work perfectly fine.
select sample.name, ABS((COALESCE(sample.openingbalance, 0)) + COALESCE(trs.TotalAmount, 0)) from sample left join (select ledger,sum(amount) AS TotalAmount from transaction group by transaction.ledger) AS trs on sample.name = trs.ledger
I want to write this query so that it is executed in laravel framework
i tried the following query but its not working
DB::table('sample')->select('sample.name',abs((COALESCE('sample.openingbalance',0))+COALESCE('trs.totalamount',0)))->leftjoin('transaction','sample.name','=','transaction.ledger')->select('ledger','sum(amount) as totalamount')->groupBy('transaction.ledger as trs') ->get();
i think what you need is this.
Raw Expressions
Sometimes you may need to use a raw expression in a query. These expressions will be injected into the query as strings, so be careful not to create any SQL injection points! To create a raw expression, you may use the DB::raw method:
sample code
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
for more info please refer http://laravel.com/docs/5.1/queries#selects

Eloquent select statement based on a condition in another table

I have an laravel eloquent select statement which looks like this:
$test = Test::with(['a.b.companies']) .. and so on
Now, I want to return results for this query based on some company names in companies table.
I tried to write a where clause with various trial and errors but it doesn't work. I am new to laravel and mysql. Any help in the right direction will be good. thanks.
You may use where, for more reference : - Eloquent ORM
$test = Test::where('company_name1', '=', $company_name1)->orWhere('company_name2', '=', $company_name2)->get();

Eloquent count distinct returns wrong totals

i'm having an issue with how eloquent is formulation a query that i have no access to. When doing something like
$model->where('something')
->distinct()
->paginate();
eloquent runs a query to get the total count, and the query looks something like
select count(*) as aggregate from .....
The problem is that if you use distinct in the query, you want something like
select count(distinct id) as aggregate from .....
to get the correct total. Eloquent is not doing that though, thus returning wrong totals. The only way to get the distinct in count is to pass an argument through the query builder like so ->count('id') in which case it will add it. Problem is that this query is auto-generated and i have no control over it.
Is there a way to trick it into adding the distinct on the count query?
P.S Digging deep into the builders code we find an IF statement asking for a field on the count() method in order to add the distinct property to the count. Illuminate\Database\Query\Grammars\BaseGrammar#compileAggregate
if ($query->distinct && $column !== '*')
{
$column = 'distinct '.$column;
}
return 'select '.$aggregate['function'].'('.$column.') as aggregate';
P.S.1 I know that in SQL you could do a group by, but since i'm eager loading stuff it is not a good idea cause it will add a IN (number of id's found) to each of the other queries which slows things down significantly.
I faced the exact same problem and found two solutions:
The bad one:
$results = $model->groupBy('foo.id')->paginate();
It works but it will costs too much memory (and time) if you have a high number of rows (it was my case).
The better one:
$ids = $model->distinct()->pluck('foo.id');
$results = $query = $model->whereIn('foo.id', $ids)->paginate();
I tried this with 100k results, and had no problem at all.
This seems to be a wider problem, discussed here:
https://github.com/laravel/framework/issues/3191
https://github.com/laravel/framework/pull/4088
Untill the fixes are shipped with one of the next Laravel releases, you can always try using the raw expressions, like below (I didnt test it, but should work)
$stuff = $model->select(DB::raw('distinct id as did'))
->where('whatever','=','whateverelse')
->paginate();
Reference: http://laravel.com/docs/queries#raw-expressions
$model->where('something')->distinct()->count('id')->paginate();