How can i orderby and groupby in one query in laravel - eloquent

I'm facing a problem when trying to order after using groupBy
I wanna sort the grouped entries but its not working here is what I was trying to do
$errors = UserErrors::all()->groupBy('user_id')->orderBy('id');

$errors = UserErrors::groupBy('feild_name')->orderBy('feild_name','DESC')->get();
Example as below
$query->where('feild_name', '=', 'active')
->groupBy('feild_name')
->orderBy('date','DESC')
->get();

Related

Using CTE (WITH queries) in Laravel query builder

In a project, I'm using a Common Table Expression (CTE) in Postgres for a recursive expression on a table. The recursive expression figures out all child rows under a parent.
I'm using the Laravel framework with query builder to write this query. I would like to avoid raw queries. I am looking for a way to chain the CTE in the query builder syntax, but I end up with a raw query (DB::select('raw query here')).
Is there a way that I can chain the CTE part? Like below in pseudo code:
DB::statement('WITH RECURSIVE included_parts(sub_part, part, quantity) AS (
SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'
UNION ALL
SELECT p.sub_part, p.part, p.quantity
FROM included_parts pr, parts p
WHERE p.part = pr.sub_part')
->select('subpart')
->table('included_parts')
->join('bar', 'foo.id', '=', 'bar.foo_id')
->etc etc more query expressions
I've created a package for common table expressions: https://github.com/staudenmeir/laravel-cte
$query = 'SELECT sub_part, part, quantity FROM parts [...]';
DB::table('included_parts')
->withRecursiveExpression('included_parts', $query, ['sub_part', 'part', 'quantity'])
->select('subpart')
->join('bar', 'foo.id', '=', 'bar.foo_id')
->[...]
You can also provide a query builder instance:
$query = DB::table('parts')
->where('part', 'our_product')
->unionAll(
DB::query()->[...]
)
DB::table('included_parts')
->withRecursiveExpression('included_parts', $query, ['sub_part', 'part', 'quantity'])
->select('subpart')
->join('bar', 'foo.id', '=', 'bar.foo_id')
->[...]

Multiple DB update query using Laravel 5

I'm new in Laravel and I'm trying to update mysql table's multiple rows using one query. I need to update for example 100 rows like this:
$q = \DB::table('exmaple')
->where('exampleID', $array)
->update(array('Viewed' => 1));
$array is array with ID-s.
I have try also to implode array to string, then execute query, but with no result. Can anyone help?
Does this work for you:
$q = \DB::table('example')
->whereIn('exampleID', $array)
->update(array('Viewed' => 1));
whereIn() accepts an array as a second parameter so all IDs in this array will be affected by the query.

Multiple inner joins with filter in Laravel 5 Eloquent query efficieny

I have the following models and relations:
Ads has many-to-many with Cities
Ads has many-to-many with Categories
Now I want to get Ads for a specific City and specific Category. So in SQL I do the following and getting the correct result:
select * from ads
inner join ad_cities on ad_cities.adId = ads.id
inner join ad_categories on ad_categories.adId = ads.id
where ad_cities.cityId = 1525
and ad_categories.categoryId = 6
I know it can be done using DB:table(xxxx)->join->....
But I want to know if the same can be done on the model without taking the DB:table approach.
I tried the following and getting the result, but the query generated doesn't seem to be efficient.
return Category::find(6)
->ads()
->whereHas('cities', function ($query) {
$query->where('cityId', '=', '1525');
})
->where('statusName', '=', 'PUBLISHED')
->orderBy('publishedAt', 'DESC')
->simplePaginate($pageSize);
This generated the following query:
select `ads`.*, `ad_categories`.`categoryId` as `pivot_categoryId`, `ad_categories`.`adId` as `pivot_adId` from `ads` inner join `ad_categories` on `ads`.`id` = `ad_categories`.`adId` where `ad_categories`.`categoryId` = '6' and (select count(*) from `cities` inner join `ad_cities` on `cities`.`id` = `ad_cities`.`cityId` where `ad_cities`.`adId` = `ads`.`id` and `cityId` = '1525') >= 1 and `statusName` = 'PUBLISHED' order by `publishedAt` desc limit 16 offset 0
Appreciate your help.
Thanks,
Velu
I've spent quite some time banging my head against this one in my own projects, and the best I can some up with is this:
return Category::find(6)
->ads()
->join('ad_cities', 'ad_cities.adId', '=', 'ads.id')
->where('ad_cities.cityId', 1525)
->where('statusName', '=', 'PUBLISHED')
->orderBy('publishedAt', 'DESC')
->simplePaginate($pageSize);
It's something, right? It gives you the right SQL and preserves the Eloquent API to some extent. The other thing I've been doing, with queries that I couldn't even shoehorn into this, is using hydrate and hydrateRaw after fetching with raw SQL.
This way, when someday I figure out how to use Eloquent effectively and/or Eloquent matures, the interface between Model and Controller will still be right and I can just replace the SQL with ORM goodness.
Also, let me know if you find a better way.

Laravel 3 Eloquent How to select column as

I'm trying to figure out how to give a column an alias using Eloquent.
So, in other words, how do I execute the following mysql query using Eloquent?
SELECT occupation AS test FROM users WHERE occupation = 'PIMP';
Thx in adv!
Eloquent returns a regular Fluent query. So you can try something like this (assuming your model name is 'User'):
$user = User::where_occupation('pimp')->get(array('occupation as test'));
This is how I have been able to do this in Laravel 5 using select() and passing the col name and the alias to that method (here I'm also using groupby() to restrict it to "DISTINCT" return values then using toarray() to return any array instead of a Collection Object:
$results = asset::select('model_code__c AS option')->whereRAW("model_code__c <> '' AND status = 'A'")->groupby('model_code__c')->get()->toarray();

Zend Framework - applying order by on a nested query

This might be a very simple thing. Check out the normal sql query below
(select * from shopping order by shopping_id desc limit 5) order by RAND()
This query runs successfully in mysql - not sure if this is the right way of doing it - but it works. It gets the last 5 ids from shopping table and randomly orders them everytime
I want to achieve this in Zend. I'm not sure how to execute the first part and then apply the RAND clause to the results - what I have below does not do that.
$select = $this->select()
->from(array('sh'=>'shopping'))
->order('shopping_id desc')
->limit(5)
->order('RAND()');
Why not take a slightly different approach which will acheive the same results. If you drop the subselect and the order by RAND() you can get the rows very quickly from the database, then when you are working with the rows, you could always randomize them.
$select = $this->select()
->from(array('sh'=>'shopping'))
->order('shopping_id desc')
->limit(5)
$rows = $this->fetchAll($select);
// take it from a rowset object, convert to an array:
$rowArray = array();
foreach ($rows as $row) $rowArray[] = $row;
shuffle($rowArray);
The Zend_Db_Expr class lets you do that. You create a new instance of the Zend_Db_Expr class and using its constructor you pass in the expression as a string: "RANDOM()".
$select = $this->select()
->from(array('sh'=>'shopping'))
->order('shopping_id desc')
->limit(5)
->order(new Zend_Db_Expr('RANDOM()'));