I've a following attendance table:
id | grade_id | subject_id | date | students
1 | 2 | 6 | 2020-05-05 | [3,6,8,11,17,21,20,19]
I want to fetch all rows with name of all students from array of Ids.
What I've tried is:
$result[] = Attendance::where('date', '=', $day)
->with('grades', 'subjects')
->join('students', function($join) {
$join->on('students.id', '=', 'attendances.id')
->where('students.id', '=', 'attendances.students');
})->get();
But couldn't get result. Please help me!
It is not a proper table structure.Will be better if you make another table like
id | attendance_id | student_id
1 | 1 | 3
1 | 1 | 6
And make its relation in model with attendance and student table.This way table will be normalized and will be easy to handle relationship.
Related
I am trying to join 2 tables and get the latest unique results using whereRaw() and leftJoin() with Laravel eloquent.
I have 2 tables:-
skills table (has timestamps):-
| id| name | icon |
| 1 | skill 1 | skill1.png |
| 2 | skill 2 | skill2.png |
| 3 | skill 3 | skill3.png |
scores table (has timestamps):-
| id| player_id | skill_id | score |
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 1 |
| 3 | 1 | 3 | 1 |
| 4 | 1 | 2 | 2 |
I would like to return all skills but only the latest entry(by id), so for the above snippet I should get:-
| id| player_id | name | skill_id | score |
| 1 | 1 | skill 1 | 1 | 1 |
| 3 | 1 | skill 3 | 1 | 1 |
| 4 | 1 | skill 2 | 2 | 2 |
I can get the latest unique records by using:
return SkillScores::where('player_id', $this->id)
->whereRaw('id in (select max(id) from skills group by (name))')
->get();
I can get the skill names by using:-
return SkillScores::where('player_id', $this->id)
->leftJoin('skills', 'skill_scores.skill_id', '=', 'skills.id')
->get();
but when I combine them I get an SQLSTATE[23000] error
return SkillScores::where('player_id', $this->id)
->whereRaw('id in (select max(id) from skills group by (name))')
->leftJoin('skills', 'skill_scores.skill_id', '=', 'skills.id')
->get();
Can anyone help me figure out what is going wrong?
EDIT:-
It turns out that the SQLSTATE[23000] error is occuring because I have an id column in both tables and I havent told it which one I am referencing, the below fixes the issue and gives me the correct result.
return SkillScores::where('player_id', $this->id)
->whereRaw('skill_scores.id in (select max(skill_scores.id) from skill_scores group by (skill_id))')
->leftJoin('skills', 'skill_scores.skill_id', '=', 'skills.id')
->get();
I think there is a minor problem on your expected result(id and name is not matching) but i made it work as following;
The query;
SELECT scores.*, skills.*
FROM scores
INNER JOIN (SELECT skill_id, max(id) AS maxId
FROM scores
WHERE player_id = 1
GROUP BY skill_id) AS sub ON sub.maxId = scores.id
INNER JOIN skills ON skills.id = scores.skill_id;
The eloquent version (You may replace it with DB::table() if you want)
$subQuery = Score::where('player_id', DB::raw($this->id))
->groupBy('skill_id')
->select('skill_id', DB::raw('MAX(id) as maxId'));
return Score::join(DB::raw('(' . $subQuery->toSql() . ') as subQuery'), 'subQuery.maxId', '=', 'scores.id')
->join('skills', 'skills.id', '=', 'scores.skill_id')
->get(['scores.*', 'skills.*']);
I have two tables as shown below. I am using Laravel DB method to join this table. But I am not getting how can I get the count of marks of students as per failed or passed. 0-failed 1-passed.
Expected result:
1. Student Name
2. Student Id,
3. Count of failed based on student Id as count_failed
4. Total Marks based on student Id as total_marks
table students
`+----+-----------+
| id | name |
+----+-----------+
| 1 | John Doe |
| 2 | Mark P |
| 3 | Pen Henry |
+----+-----------+`
table students_marks:
+----+------------+-------+-----------+
| id | student_id | marks |is_failed |
+----+------------+-------+-----------+
| 1 | 1 | 55 | 0 |
| 2 | 2 | 44 | 1 |
| 3 | 1 | 11 | 1 |
| 4 | 2 | 10 | 0 |
| 5 | 2 | 11 | 1 |
| 6 | 2 | 20 | 0 |
+----+------------+-------+-----------+
Below is query which I used:
$users = DB::table('users')
->join('contacts', 'students.id', '=', 'students_marks.user_id')
->select('student.*')
->get();
I am unable to get how can we use count() with conditional SQL in select() of laravel?
Use conditional aggregation:
$users = DB::table('students s')
->leftJoin('students_mark sm', 's.id', '=', 'sm.user_id')
->groupBy('sm.id')
->select(DB::raw('s.id, s.name, SUM(sm.is_failed) AS num_failed, COUNT(sm.user_id) AS total_cnt'))
->get();
This corresponds to the following raw MySQL query:
SELECT
s.id,
s.name,
SUM(sm.is_failed) AS num_failed,
COUNT(sm.user_id) AS total_cnt
FROM students s
LEFT JOIN students_marks sm
ON s.id = sm.user_id
GROUP BY
s.id;
Note: It is acceptable in ANSI SQL to select the name field in the above GROUP BY query assuming that student#id is the primary key column for that table. If the above query gives an ONLY_FULL_GROUP_BY error, then simply add s.name to the GROUP BY clause.
$users = DB::table('users')
->join('contacts', 'students.id', '=', 'students_marks.user_id')
->select('student.*', DB::raw("count(students_marks.is_failed) as count")))
->where('status', '=', 0)
->get();
Try this.
If this is not clear or doesn't work refer this
Try this code snippet
$table = DB::table('students_marks');
$table = $table->select(
\DB::raw('SUM(if(is_failed = '0', 1, 0)) AS failed'),
\DB::raw('SUM(if(is_failed = '1', 1, 0)) AS passed'),
\DB::raw('SUM(marks) AS total'));
$table = $table->Join('students', 'students.id', '=', 'students_marks.student_id');
$table = $table->get();
Try this
$users = DB::table('students s')
->leftJoin('students_mark sm', 's.id', '=', 'sm.student_id')
->groupBy('s.id','s.name')
->selectRaw("s.id,s.name,SUM(sm.is_failed) AS count_failed,SUM(sm.marks) as total_marks")
->get();
i want to get each id's total count from another table named assign job. i saved user data into my users table and i add 3 jobs into assign job table with user id.
but now i want to get total added jobs from assign job table where user ids in my users table at once.
I wrote this function
$assignjob = DB::table('users')
->join('assign_jobs', 'users.user_id', '=', 'assign_jobs.user_id')
->get()
->count();
but this shows me total count in my assign job table. but i want to get different count for each user ids.
i want to assign different color rows with this assign job total count values.
can any one help me.
User Table:
|---------------------|------------------|
| user_id | name |
|---------------------|------------------|
| 123 | john |
|---------------------|------------------|
| 234 | peter |
|---------------------|------------------|
assign job table:
|---------------------|------------------|
| id | user_id |
|---------------------|------------------|
| 1 | 123 |
|---------------------|------------------|
| 2 | 123 |
|---------------------|------------------|
| 3 | 234 |
|---------------------|------------------|
| 4 | 234 |
|---------------------|------------------|
You need to use GROUP BY clause for your user's id column and add COUNT() to your select. Try:
DB::table('users')
->select('users.user_id', DB::raw('COUNT(assign_jobs.user_id) AS jobs_count'))
->join('assign_jobs', 'users.user_id', '=', 'assign_jobs.user_id')
->groupBy('users.user_id')
->get();
Select distinct usesr ID to loop into it to have the count for each users
try this:
add below relation to User Model:
public function assignJobs()
{
return $this->hasMany(AssignJob::class, 'user_id', 'user_id');
}
and in controller:
User::withCount('assignJobs')->get();
I have a variable called $category which a user selects. On submit I need to look inside a table (profiles) for where the $category matches and pull back all of those profiles then look into the likes table and return all matching records for the returned profiles.
My database looks like:
TABLE: profiles
ID | username | category
-------------------------
1 | x | band
2 | y | airline
3 | z | airline
TABLE: likes
ID | account_id | likes | created_at
---------------------------------------
1 | 2 | 1000 | 21/03/2016
2 | 2 | 2000 | 22/03/2016
3 | 1 | 3000 | 22/03/2016
My code is the following:
$category = "band";
$profiles = DB::table('profiles')
->join('likes', 'profiles.id', '=', 'likes.account_id')
->where('category', '=', $category)
->select('profiles.*', 'likes.likes', 'likes.created_at')
->get();
account_id in the likes table will be the same as id in the profiles table. Also there maybe multiple like records for each profile.
The query just doesn't seem to work and it returns nothing back. I'm using laravel 5.2.
$profiles = DB::table('profiles')
->leftJoin('likes', 'profiles.id', '=', 'likes.account_id')
->where('profiles.category', '=', $category)
->select('profiles.*', 'likes.likes', 'likes.created_at')
->get();
I have a table entries similar as follows:
+---------+---------+----------+
| Test_id | User_id | Attempts |
+---------+---------+----------+
| 12 | 5 | 1 |
| 13 | 5 | 1 |
| 12 | 5 | 2 |
+---------+---------+----------+
Now I want to select the elements group by test_id and should get the latest entry.
I tried this query:
$tests_took = Testresult::where('course_id', $courseId)
->where('user_id', Auth::id())
->groupby('test_id')
->orderBy('attempts', 'desc')
->get();
When I display the result, I'm getting the first two rows only (only one row for one test_id - which I what I want.) But instead of the last row for the test_id=12, it shows the first row. I always want the biggest attempt to be displayed.
My current output is like:
| 12 | 5 | 1 |
| 13 | 5 | 1 |
But I want this:
| 12 | 5 | 2 |
| 13 | 5 | 1 |
How can I achieve this? to get the latest row as the first array element when I use groupby or is there any other way to do this?
ORDER BY and GROUP BY don't work very well together...
If you simply want the highest attempt per test_id i suggest using the MAX() function:
$tests_took = Testresult::select('test_id', 'user_id', DB::raw('MAX(attempts) AS max_attempts'))
->where('course_id', $courseId)
->where('user_id', Auth::id())
->groupby('test_id')
->get();
You may use the following lines:
Testresult::select('*')
->join(DB::raw('(Select max(id) as last_id from Testresult group by test_id) LatestId'), function($join) {
$join->on('Testresult.id', '=', 'LatestId.last_id');
})
->orderBy('attempts', 'desc');
}