My Laravel query builder return null:
$country = DB::table('participate_company')
->join('company', 'company.company_id', '=', 'participate_company.company_id')
->join('country', 'country.country_id', '=', 'company', 'company.country_id')
->join('competition', 'competition.competition_id', '=', 'participate_company.competition_id')
->select('country.country_name', DB::raw('COUNT(company.country_id) as total'))
->groupBy('company.country_id')
->groupBy('country.country_name')
->get();
Table design:
1. Participate_company
competition_id (pk/fk)
company_id (pk/fk)
2. company
company_id (pk)
company_name
country_id (fk)
3. country
country_id (pk)
country_name
4. competition
competition_id (pk)
competition_year
I want to produce result of count distinct country based on competition year. For example competition year = 2012, country_name = England, count(total) = 20. But my current query produce null.
SQLFiddle : http://sqlfiddle.com/#!9/a2092f/1
I suggest using Laravel ORM Relationship and Eager Loading to solve this problem.
In Company model, we would define country()method:
public function country() {
return $this->belongsTo(Country::class, 'country_id', 'id');
}
In Competition model, define method
public function company() {
return $this->belongsToMany(Company::class);
}
So in controller you can call groupBy :
Competition::with('company:id,country_id')->get()->groupBy('year');
We will catch country_id in each company which is in relations of years.
I just tested a simple example, after that, we will loop over this collection and count them .
Hope this's usefull.
P/s. As using by models, my table's names: companies, countries, competitions, company_competition
Related
I'm using laravel 7 and
I have 3 tables shown below. I want first three students data instead of all student. tables have many to many relationship.
groups
id
name
students
id
name
group_student_pivot
group_id
student_id
created_at
I have below relationship in models
Groups model
public function students()
{
return $this->belongsToMany(Student::class,'group_student_pivot')->withPivot(['status'])->withTimestamps();
}
Student model
public function groups()
{
return $this->belongsToMany(Group::class,'group_student_pivot')->withPivot(['status'])->withTimestamps();
}
$groups = Group::whereIn('id',$groupIds)->with('students')->get();
In above query I want first 3 students data instead of all students.
You can get 3 records like this:
$groups = Group::whereIn('id',$groupIds)->with('students', function($q){
$q->take(3);
})->get();
You can use with and whereHas method
$groups = Group::with('students')->whereHas('students', function($q){
$q->take(3);
})->whereIn('id',$groupIds)->get();
I have a two models that have a many-to-many relationship, with some addtional fields on the pivot table:
Shift table:
------------
id - uuid
date - date
address - string
...
Employee table:
---------------
id - uuid
first_name - string
...
shift_employee table:
---------------------
id - integer
shift_id - uuid
employee_id - uuid
hours_worked - integer
...
Now, I'm making a Lens in Laravel Nova, and I want to use the query object to check if any of the instances on shift_employee related to a specific shift has a value bigger than 0 for hours_worked on the shift_employee table.
My first idea is to somehow use whereHas assuming that the Shift model has a relationship employees, like this:
$query->whereHas('employees' function ($q) {
$q->where('hours_worked', '>', 0);
});
But... this is not working... There are shifts with more than 0 hours_worked for certain employees and this query string is not working for me. How would I do this?
First make sure your models are modeled correctly. If they are, you can access any attribute of an intermediate table with the pivot attribute as below:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
/**
* The users that belong to the role.
*/
public function users()
{
return $this->belongsToMany('App\User');
}
}
exemple :
$user = App\User::find(1);
foreach ($user->roles as $role) {
echo $role->pivot->created_at;
}
In your case, try :
$employee = Employee::with('Shift');
foreach($employee as $e){
$employeeHw[] = $e->shift_employee->where('hours_worked', '>', 0)->get();
}
I'm also new to laverel, so I'm not absolutely sure it works, but in theory: P
Usually in these cases I use the query bilder with join which I find easier
$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();
I have this database structure
table users table office_user table offices
----------- ----------------- -------------
id * id * id *
full_name user_id name
office_id
joined_at
So in my project every office has many users and user can be joined to many offices in date (joined_at)
User.php model
public function offices()
{
return $this->belongsToMany('App\Office)->withPivot('joined_at');
}
Office.php model
public function users()
{
return $this->belongsToMany('App\User)->withPivot('joined_at');
}
OfficeController.php
public function show(Office $office)
{
$users = User::with(array('phones', 'offices' , function($query)
{
$query->orderBy('joined_at', 'desc');
}))->get();
return view('dashboard.offices.show', compact(['office', 'users']));
}
I need two things :
1- Get current users list for every office
2- Count of current users in every office
I already achieve this:
<h3>{{ $office->name }}</h3><span>{{ $office->users->count() }}</span>
#foreach ($office->users as $user)
<li>{{ $user->full_name }}</li>
#endforeach
But the result is not as expected it gives me all users in certain office and count of them regardless there joined date
I want the list of last joined users to this office and count of them according joined_at field in pivot table
Thank you and Sorry for my english
But the result is not as expected it gives me all users in certain office and count of them regardless there joined date
When you do $office->users->count() that is the expected behavior because you are retrieve all the associated users of every office at any time, so given that you returned all this users, the count() executed in the collection will count all of them.
Your pivot attribute is just a timestamp, so how would you reduce the number of users returned? users that joined the office today/in the last hour/in the last 15 min maybe?
If so, you can add constrains to your count() method to get the results you want.
As an example, in the following lines we are gonna constraint the associated offices that has a joined_at that belongs to today:
public function show(Office $office)
{
$users = User::with([
'phones',
'offices' => function ($offices) {
$offices->whereDate('joined_at', '>', now()->startOfDay());
},
])->get();
return view('dashboard.offices.show', compact([office, 'users']));
}
Check this section of the documentation:
Constraining Eager Loads
Sometimes you may wish to eager load a relationship, but also specify
additional query conditions for the eager loading query. Here's an
example:
$users = App\User::with(['posts' => function ($query) {
$query->where('title', 'like', '%first%');
}])->get();
In this example, Eloquent will only eager load posts where the post's
title column contains the word first. You may call other query
builder methods to further customize the eager loading operation:
$users = App\User::with(['posts' => function ($query) {
$query->orderBy('created_at', 'desc');
}])->get();
I have 3 models and a pivot table:
SchoolYear - model
id
Course - model
id
schoolyear_id
course_student - pivot table
course_id
student_id
Student - model
id
Relationships are:
a SchoolYear hasMany Course
a Course belongsToMany Student trough course_student
a Student belongsToMany Course trough course_student
What is the fastest, more elegant way to find the students rolled in to a schoolyear and also to be able to sort it by Student properties?
$year = SchoolYear::firstOrCreate(['anul'=>Carbon::now()->year]);
$courses = $year->courses;
$students = collect([]);
foreach($courses as $course){
$course_students = $course->students;
foreach($course_students as $course_student){
$students->push($course_student);
}
}
dd($year, $students);
Eloquent provides a set of methods to query relationship existence. has() if there are not conditions, or whereHas() if there is a condition.
So, in your case, you want the students that have a related school year.
$year = SchoolYear::firstOrCreate(['anul'=>Carbon::now()->year]);
// assumes Student has a "courses" relationship,
// and Course has a "schoolYear" relationship
$students = Student::whereHas('courses.schoolYear', function ($query) use ($year) {
return $query->where('anul', $year->anul);
})
->get();
dd($year, $students);
I need to get count of a records groupBy using with() function known as eager loading. I have two tables having one-to many relationship.
Properties:
id
name
address
Banner_Invoices:
id
property_id
start_date
end_date
Property Model has following relationship function with Banner_Invoices table:
public function bannerInvoices()
{
return $this->hasMany('BannerInvoice');
}
Now following is my query:
$properties = Property::with(array('country', 'city',
'bannerInvoices' => function($query) {
$query->where('end_date','>',date(date("Y-m-d")))
->groupBy('banner_invoices.status')
->select(DB::raw('COUNT(banner_invoices.id)')) ;
}))->get();
I am not been able to get the count of records groupBy with the status of banner Invoices. It gives me the records of banner_invoices table corresponding to a particular property.