How to retrieve data from a table from the same column but having different values in laravel 4 - laravel-4

i have a table called (tickets) with (movie_id)column and (amount)column,
how can i retrieve a movie with the highest amount?thank you
$movies = DB::table('tickets')->where('movie_id',$id)->having('amount', '>', 1000)->get();

Try this:
$movies = DB::table('tickets')->where('movie_id',$id)->orderBy('amount', 'desc')->get();
Or,
$movie = DB::table('tickets')->where('movie_id',$id)->orderBy('amount', 'desc')->first();
to retrieve only one record.

Related

Laravel query builder where condition from relationship table

I have following tables
Messages:
user_id
group_id
text
created_at
And
group_users:
user_id
left_at
group_id
These tables have relationship via "group_id".
I need "Messages" that created before "group_user" left group.
In other word, i need a query like this:
$messages = Message::where('created_at','<',group_user.left_at)->get();
How can i achieve this?
You can simply do it like this assuming you have the user ID at hand:
Message::join('group_users', 'messages.group_id', '=', 'group_users.group_id')
->where('group_users.user_id', $id)
->where('group_users.left_at', '>', 'messages.created_at')
->get();
it can be like the code below(untested):
in the Message model
public function group(){
return $this->belongsTo(Group::class);
}
in the controller
$messages = Message::whereHas('group', function($q){
$q->where('left_at','>','messages.created_at');
})->get();

Counting data before sending to view in Laravel

I have two tables, products and product_images, now I want to show product which has at least one image.
In controller I have a simple function in ProductController to fetch all the products:
public function products(){
$allProducts = $this->product->paginate(15);
return view('frontend.pages.products',compact('allProducts'));
}
But, I want to send the products which has at least one image of each product.
What should I do to achieve that?
Edit:
I have created relationship between tables, now how can I get my desired answer?
I have written this in the Controller:
$allProducts = $this->product->whereHas('product_images', function ($query){
$query->where();
})->get();
Assuming table schema
product
-id
-name
product_image
-id
-product_id
-url //any columns you needed
$product_ids = DB::table('product')
->join('product_image','product_image.product_id','=','product.id')
->select('product.id','roduct.name')
->groupBy('product.id')
->get();
$product_count = count($product_ids);
Eloquent has this built in.
Example
// Retrieve all posts that have three or more comments...
$posts = App\Post::has('comments', '>=', 3)->get();
In your case
In your case you could change the $allProducts line to be
$allProducts = $this->product()->has('product_image', '>=', 1)->paginate(15);
I didn't test the code above.
See documentation for more information on this topic.
https://laravel.com/docs/6.x/eloquent-relationships#querying-relationship-existence
You can use selectRaw:
$products = Product::leftJoin('product_images',function ($join){
$join->on('products.product_id','=','product_images.product_id');
})->selectRaw("products.product_id i, count(product_images.id) c")
->groupBy('products.product_id')
->where('c','>=',3)
->get();
Getting answer querying realtionship:
The query will look like following:
$allProducts = $this->product->has('Images')->paginate(15);
But, make you sure you have created relation in Model like the following:
public function Images(){
return $this->hasMany('\App\Models\ProductImages');
}
I have used hasMany relationship because one product can have multiple images.

How to get data based in comparing value in pivote table with value in required table in laravel 5.6?

I am learning larvel 5.6 so I am trying to retrieve number of messages that have id larger than last_seen_id in pivot table
I have user table which have the default columns generated by:
php artisan make:auth
and messages tables which have the following columns:
id, from, message_content, group_id
and the group table have the columns:
id,type
now there is many to many relation between the users and groups table through the custom pivot table which have the columns:
group_id,user_id,last_id_seen
now if I want to retrieve the messages which belong to same group and have larger id than last_id_seen in the pivot table how to do it?
I think you are looking for something like this:
$groupId = 1; // set to whatever you want
$lastSeenId = \Auth::user()->groups()
->where('group_id', $groupId)
->first()->pivot->last_id_seen;
$messages = Message::where('id', '>', $lastSeenId)->get();
A more robust version, which does not fail when your user does not have an entry for the group yet, would be:
$groupId = 1; // set to whatever you want
$group = \Auth::user()->groups()->where('group_id', $groupId)->first();
$lastSeenId = $group ? $group->pivot->last_id_seen : null;
$messages = Message::when($lastSeenId, function($query, $id) {
$query->where('id', '>', $id);
})->get();
Note: normally you'd use optional() in the second snippet, but Laravel 5.2 does not come with this helper...
If you want both the count() of the results and the results themselves, you can store the query in a variable and perform two queries with it. You then don't have to rewrite the same query twice:
$groupId = 1; // set to whatever you want
$group = \Auth::user()->groups()->where('group_id', $groupId)->first();
$lastSeenId = $group ? $group->pivot->last_id_seen : null;
$query = Message::when($lastSeenId, function($query, $id) {
$query->where('id', '>', $id);
});
$count = $query->count();
$messages = $query->get();

laravel relation issue in many to many case

i have three table in mysql:
1-users
table of users
2-projects
table of project
3-project_user
there is id and project_id and user_id for relation
there is two model : user and project
the relation between these table are belongsToMany
when a project create maybe one project define for two person
NOW how can i show the project of each person?
Assuming you properly defined your relationships, do
$users = User::with('projects')->get();
//show each user projects
foreach($users as $user) {
echo $user->projects;
}
//Getting project users
$projects = Project::with('users')->get();
This will give you projects list, in each list you can see which user has access or not.
Updates
Taking project with specified user_id
$projects = Project::with(['users' => function ($query) use ($user_id) {
$query->where('user_id', '=', $user_id);
}])->get();
New code
Or try to to get the user
$user = User::with('projects')->where('id', $user_id)->first();
Or via projects, constraining by user_id
$projects = Project::with('users')->whereHas('users', function ($query) use ($user_id) {
$query->where($user_id);
})->get();
the way i solve it:
//save user_id
$user_id = $request->id;
//select in project_user where user_id = $user_id
$project_user = DB::table('project_user')->where('user_id', '=', $user_id)->get();
//create an empty array
$p_id = array();
//fill empty array with project_id
foreach($project_user as $pro) {
$p_id[] = $pro->project_id;
}
//select code and id in project table where id = one of that [$p_id] array
$data = Project::select('code','id')->whereIn('id', $p_id)->get();
//return your data in json
return response()->json($data);
As far as I understood your question, you want to query Project as per user_id. Here is how you do it.
Project::with('users')->whereHas('users', function ($query) use ($user_id_array) {
$query->whereIn('id',$user_id_array);
})->get();
This will give you projects whose user_id are from $user_id_array. Let me know if you need any further help.

Order by sum column relationship in Laravel

I have this controller which grabs posts from a post table.
Every post in the posts table have the relation "hasMany" with another table likes.
Controller:
public function getDashboard(){
$posts = Post::orderBy('created_at', 'desc')->get();
return view('dashboard', ['posts' => $posts]);
}
I'd like to replace 'created at' with something like:
$post->likes->sum(like)
Don't know how to write the right syntax though.
EDIT:
Here are the tables.
Posts
--id
--body
Likes
--id
--post_id
--like
The column like can have the value 1 or -1.
I'd like to order on the summation of that column for each post.
So a post with one dislike(-1) and one like(1) will have the aggregated value of 0, hence will be placed after a post with one like(1).
You can use withCount() for this as:
Post::withCount('likes')->orderBy('likes_count')->get()
withCount() will place a {relation}_count column on your resulting
models
Update
Post::withCount(['likes' => function($q) {
$q->where('like', 1)
}])
->orderBy('likes_count')
->get()
Update2
You can use sortByDesc() to sort your collection as:
$posts = Post::get();
$posts = $posts->sortByDesc(function ($post) {
return $post->likes->sum('like');
});
If you want to sum column value from relationship and then sort records.
$users = User::addSelect(['likes' => Post::selectRaw('sum(likes) as total_likes')
->whereColumn('user_id', 'useres.id')
->groupBy('user_id')
])
->orderBy('likes', 'DESC')
->get()
->toArray();
Or
use below
$users = User::select("*",
\DB::raw('(SELECT SUM(likes) FROM likes_table WHERE likes_table.user_id = users.id) as tolal_likes'))
->orderBy('likes', 'DESC')
->get()
->toArray();

Resources