Laravel 4: Order query relation randomly and limited - php

I'm using Laravel 4 and I'm running into an issue with eloquent.
I've got it set up to grab the category, get the products and limit it to 2. However I'm having trouble getting the random element. I need it to select from two random products, rather than the newest/latest.
$products = Category::find($id)->products->take($limit);
$products->load('imageThumb');
return $products;
I'd like to keep the solution eloquent based, but if that's not an option I'll switch to a raw query code.
Thanks!

$products = Category::find($id)->products()->orderBy(DB::raw('RAND()'))->take($limit)->get();
(sorry forgot the ->get() in my original answer)

How's big is the table? If it is not too big you can use MySQL ORDER BY RAND()
http://davidwalsh.name/mysql-random
Eloquent something like:
->orderBy(DB::raw('RAND()'))

Related

How to query whereIn inside json column in laravel 5.3?

I have been working with a laravel 5.3 version and in a table i have a json column where i have saved average rating of a category table.
so, A product category table has a column "detail" as a json data type which saves avgRating.
I want to run a query inside that json column. And i want to filter that category with a average rating. So, from the frontend side rating comes in a parameter with a comma seperated so that category can be filtered with multiple ratings.
$productCategory = ProductCategory::query();
$ratings = explode(',',$params['ratings']);
$productCategory = $productCategory->whereIn('detail->avgRating',$ratings)->get();
I want to achieve something like this.
I am using Postgres
It turns out that there was too much uncertainty at the time when the question was asked. Once the asker separated the problems and figured out that the raw query of
DB::select(DB::raw("SELECT * FROM product_categories where detail->>'avgRating' in ('2.0','4.0')"));
works in Postgres, the asker from that point onwards had a much easier time figuring out the actual solution in the where clause. I presuppose that it was
detail->>avgRating
instead of
detail->avgRating
but from the comment section that was not yet confirmed. But the moral of the story is that whenever one has an eloquent problem that might be related to the RDBMS, then it makes a lot of sense to first sort out the raw query and then, having solid knowledge about what should be generated, at that point one can switch to the Eloquent code and apply the solution there.
You should use whereJsonContains or whereRaw:
$productCategory->whereJsonContains('detail->>avgRating',$ratings)->get();
OR
$productCategory->whereRaw('JSON_CONTAINS(detail->>avgRating, ?)', $ratings)->get();

Cakephp - get database data from not associated models

I wanted to ask, how can i get data from one table and use this in other find.
For example, i have films table.
I want to get highest rated 3 films. Result should return 3 ID's.
Now, i want to create other query from not associated table, and pass this 3 ID's as "conditions" to find data in other table.
I dont want to use associations, because, data is stored in many databases, and this is problematic.
Thank You.
Once you've got your film IDs you can use in to filter the results from your other Model:-
$filmIds = ['32','55','75'];
$query = TableRegistry::get('Model')->find()
->where(function ($exp, $q) use ($filmIds) {
return $exp->in('film_id', $filmIds);
});
// WHERE film_id IN ('32','55','75')
Check out the docs section on advanced conditions.
If you need to get your film IDs into the correct format (i.e. that shown in the example code) you can use Hash::extract() on the results from your previous query.
if your cakephp version 3.x you can use subqueries in fairly intuitive way
$films = TableRegistry::get('Films')->find('highestRated')
->select(['id'])
->limlt(3);
$query = $related->find()
->where(['id' => $films]);
Subqueries are accepted anywhere a query expression can be used. For example, in the select() and join() methods. http://book.cakephp.org/3.0/en/orm/query-builder.html#subqueries

Laravel 5 : How do I retrieve 10 records of each kind of data in a column?

I realise in Laravel 5 Eloquent there is a function called groupBy. I usually used it like so
->groupBy('rating');
Let's say in rating column, there are 3 types of ratings in integer : 1,2 and 3How do I limit it to 10 records for each kind of rating? Preferably using Eloquent but if that's not possible, I'll still accept query builder method.
Union should work:
$type1 = Model::whereType(1)->take(10);
$type2 = Model::whereType(2)->take(10);
$type3 = Model::whereType(3)->take(10);
$types = $type1->union($type2)->union($type3)->get();
If i'm not getting your question wrongly, your question mysql solution would be Get top n records for each group of grouped results
But when we convert our desire query to laravel, so its will look alike:
$Rating1 = Model::whereRating(1)->take(10);
$Rating2 = Model::whereRating(2)->take(10);
$Rating3 = Model::whereRating(3)->take(10);
$result = Model::unionAll($Rating1)->unionAll($Rating2)->unionAll($Rating3)->get();
And its also one query not multiple as per laravel 4.2 docs, If you still confuse to implement it, let me know.

Laravel: Order by specific ID

I've been looking like crazy but I can't seem to find a way of achieving something similar to this with Laravel's Eloquent:
select id,name
from friends
order by id=5 desc
Example taken from the following link: mysql SQL: specific item to be first and then to sort the rest of the items
I was hoping a simple Group::orderBy('id', $id, 'DESC')->get() would work, but no such luck.
I've also looked into using DB instead but the orderBy method for that class takes in exactly the same arguments and doesn't have an option for specific IDs. Are there any alternatives?
Thank you very much for all the help!
not sure , but may be you could try using orderByRaw(), like,
$id = 5;
Group::orderByRaw(DB::raw("FIELD(id, $id)"))
->get();

Laravel Query Builder where max id

How do I accomplish this in Laravel 4.1 Query Builder?
select * from orders where id = (select max(`id`) from orders)
I tried this, working but can't get the eloquent feature.
DB::select(DB::raw('select * from orders where id = (select max(`id`) from orders)'));
Any idea to make it better?
You should be able to perform a select on the orders table, using a raw WHERE to find the max(id) in a subquery, like this:
\DB::table('orders')->where('id', \DB::raw("(select max(`id`) from orders)"))->get();
If you want to use Eloquent (for example, so you can convert your response to an object) you will want to use whereRaw, because some functions such as toJSON or toArray will not work without using Eloquent models.
$order = Order::whereRaw('id = (select max(`id`) from orders)')->get();
That, of course, requires that you have a model that extends Eloquent.
class Order extends Eloquent {}
As mentioned in the comments, you don't need to use whereRaw, you can do the entire query using the query builder without raw SQL.
// Using the Query Builder
\DB::table('orders')->find(\DB::table('orders')->max('id'));
// Using Eloquent
$order = Order::find(\DB::table('orders')->max('id'));
(Note that if the id field is not unique, you will only get one row back - this is because find() will only return the first result from the SQL server.).
Just like the docs say
DB::table('orders')->max('id');
For Laravel ^5
Orders::max('id');
I used it is short and best;
No need to use sub query, just Try this,Its working fine:
DB::table('orders')->orderBy('id', 'desc')->pluck('id');
Laravel 5+:
DB::table('orders')->orderBy('id', 'desc')->value('id');
For objects you can nest the queries:
DB::table('orders')->find(DB::table('orders')->max('id'));
So the inside query looks up the max id in the table and then passes that to the find, which gets you back the object.
You can get the latest record added to the Orders table you can use an eloquent method to retrieve the max aggregate:
$lastOrderId = Order::max('id');
To retrieve a single row by the id column value, use the find method:
$order = Order::find(3);
So combining them, to get the last model added to your table you can use this:
$lastOrder = Order::find(Order::max('id'));

Categories