Laravel Convert SQL to Eloquent : order by a sum() - sql

I'm new to Eloquent and Laravel. I tried multiple syntaxes but I can't find a way to make it work. Here is the query I would like to convert :
SELECT category, SUM(amount) AS `total_cat` FROM expenses GROUP BY category ORDER BY `total_cat` DESC
And here's my Model for the "expenses" table :
class Expense extends Model
{
use HasFactory;
protected $fillable = ['date', 'title', 'amount', 'category'];
}
The idea here is to get the sum of expenses for each category (the alias is not necessary). The query is working just fine in pure PHP. Thanks for your help :)

This may be the solution, I haven't test but it seem fits the theory within the eloquent functions
Expense::select([
'category',
DB::raw('SUM(category) AS category_sum')
])
->groupBy('category')
->orderBy('total_cat', 'desc')
->get()

Here's what worked for my initial problem:
Expense::select([
'category',
DB::raw('SUM(amount) AS total_cat') ])
->groupBy('category')
->orderBy('total_cat', 'desc')
->get();

Related

Select from select using Laravel eloquent

I want to get all user's favourite products. The query should be like this:
SELECT *
FROM products
WHERE id IN (SELECT id FROM favourites WHERE user_id == Auth::id())
How can I query with eloquent?
You're trying to achieve something like this:
In the oficial documentation you can find the explanation of Advanced where clauses
DB::table('products')
->whereIn('id', function($query)
{
$query->select('id')
->from('favourites')
->where('favourites.user_id', Auth::id());
})
->get()
The final result will be (you can see this dumping the query using toSql() method instead of get()) :
select * from `products` where `id` in (select `id` from `favourites` where `favourites`.`user_id` = ?)
What do you mean to saying "How can I do it"? Are you asking how to structure it or how to query with eloquent?
If you asking the query:
Product::whereIn('id', Favourite::select('id')->whereUserId(Auth::id())->get()->toArray())->get();
should work.
If you asking structure, you should define relations in models.
On User model;
public function favourites()
{
return $this->hasMany(Favourite::class, 'user_id');
}
and on Favourite model;
public function favoriteProduct()
{
return $this->belongsTo(Product::class, '[the product_id column on favourites table]');
}
and then you can access like;
$userFavourites = User::with('favourites.favoriteProduct')->whereId(Auth::id())->favourites;
on your view:
#foreach($userFavourites as $userFavourite)
{{ $userFavourite->favouriteProduct }}
#endforeach
this is the simplest. on the other hand; you can use Has Many Through relationship.
And this would be the cleanest way.

Laravel eloquent query to get the result groupBy(month)

How to get a result with groupBy(month('start_date'))
So far I have
$this->data['earnings'] = DB::table('documents')
->leftJoin('users','users.id', '=', 'documents.users_id')
->leftJoin('users_editors','users_editors.user_id','=','users_id')
->groupBy(month ('start_date'), 'DESC')
->sum('amount')
->get();
I am trying to get earnings for all the editors groupBy month which will take month from start_date to have a groupBy on.
Thanks
In order to use (My)SQL functions you need raw statements, that are not processed and bound by PDO or, in this case, treated as a field name:
->groupBy(DB::raw('month(start_date)'))
In order to make it work as you expect:
->selectRaw('month(start_date) as month, sum(amount) as sum')
->groupBy(DB::raw('month desc'))
// or:
->groupBy('month')
->orderBy('month', 'desc')
->get();

kohana order group by and count

I have orm query like tthis:
$userCountries = ORM::factory('User')
->select(array(DB::expr('countries.code, COUNT("countries.id") as total')))
->join('countries')
->on('user.country_id', '=', 'countries.id')
->group_by('country.name')
->order_by('total', 'DESC')
->find_all();
What i want is country code with total users quantity from country.
I do not know what is wrong here. I spent 3 hours on it with no success.
What is wrong with this query?
Your SELECT Params is wrong
->select('countries.code', array(DB::expr('COUNT("countries.id")', 'total')))
I think the Group by should be
->group_by('countries.name') instead of ->group_by('country.name')
So Your Total Query will look like
$userCountries = ORM::factory('User')
->select('countries.code', array(DB::expr('COUNT("countries.id")', 'total')))
->join('countries')
->on('user.country_id', '=', 'countries.id')
->group_by('countries.name')
->order_by('total', 'DESC')
->find_all();`
Check this out...

OrderBy count appearing in the wrong order in Eloquent Query Builder (Laravel 4)

I have the following query:
public static function artists_most_popular() {
$artists_most_popular = DB::table('artists')
->join('fanartists', 'artists.id', '=', 'fanartists.artist_id')
->orderBy(DB::raw('count(*)', 'DESC'))
->groupBy('artists.id')
->take(50)
->get();
return $artists_most_popular;
}
As you can see from the query, I would like the data to appear in descending order by count of the times the artist_id appears in the fanartists table. However, when I use "foreach" and output this data, it appears in ascending order. Any ideas for why this is happening? I used the following query in SQL Pro, and it works as it should:
select *, COUNT(*)
from artists
join fanartists on artists.id = fanartists.artist_id
group by artists.id
order by (COUNT(*)) desc
I have changed the query little bit. Hopefully this will work.
$artists_most_popular = DB::table('artists')
->join('fanartists', 'artists.id', '=', 'fanartists.artist_id')
->select(DB::raw('artists.*, fanartists.*, COUNT(*) AS total_artists'))
->orderBy('total_artists', 'DESC'))
->groupBy('artists.id')
->take(50)
->get();
Also if you want your Artists collection to be returned (this pretends your Artists Model is called Artists), and to further enhance Anam's response, you could do something like:
$artists_most_popular = Artists::join('fanartists', 'artists.id', '=', 'fanartists.artist_id')
->select(DB::raw('artists.*, fanartists.*, COUNT(*) AS total_artists'))
->orderBy('total_artists', 'DESC'))
->groupBy('artists.id')
->take(50)
->get();

Simple SQL to Eloquent Query (Laravel)

I have two tables: users (Users) and groups (Groups).
Users
-----------------
id | username | group
1 | Bob | 2
Groups
-----------------
id | name
1 | firstgroup
2 | secondgroup
I would like to display: users.ID, users.username, group.name (1, Bob, secondgroup)
An SQL statement like so would work:
SELECT Users.id, Users.username, Groups.name
FROM Users
INNER JOIN
Groups ON Groups.id = Users.group
However, I'm struggling to write this in Eloquent, since there is no "FROM". At the moment I'm going for something along the lines of the below, using JOINS (http://laravel.com/docs/queries#joins)
$users = Users::select('id','username', 'Groups.name')->joins('Groups.id', '=', 'id')->get();
Now this isn't working - I think the joins has to come before the select but I just can't work it out :(
I think you're confusing a few things here...
You're mixing Eloquent with the lower-level DB::table('foo')->select() syntax. When you want to use Eloquent I suggest you take a look at the docs about relationships in Eloquent.
You should define your models like so:
class User extends Eloquent {
public function group()
{
return $this->belongsTo('Group', 'group');
// second parameter is necessary because you didnt
// name the column "group_id" but simply "group"
}
}
class Group extends Eloquent {
public function users()
{
return $this->hasMany('User', 'group');
}
}
This sets up all the joins you might be needing later. You can then simply use User::with('group')->all(); and have the query built and run for you.
Database: Query Builder(DB) is not a Eloquent(ORM):
Database query builder you have to inform the table names and the fields, like it says on in your related link of laravel docs: "...provides a convenient, fluent interface to creating and running database queries." like these query below:
$users = DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')
->get();
Eloquent is a ORM - Object related Mapping, it means that your class User is related to the table users (look at you files Migrations) and this class extends the Model Class, thus you can access the methods like these bellow:
class User extends Models
{
public static function usersWithGroups(){
return User::select('id', 'name', 'email')->with('groups')->get();
}
}
Observe that method is into the class User, so you can access that in a static way "User::", using Eloquent you'll have many hidden static methods that will improve you time codding, because you are inheriting de Model methods, to more details visit the Eloquent Docs at: Eloquent Docs