How to use CASE WHEN in Eloquent ORM? - php

How to use CASE WHEN in Eloquent ORM?
I'm wondering if it will work if add
$query->selectRaw('CASE WHEN (created_at = '.$daterange.') THEN 'P' as attendance) something like that, but i don't know how to use CASE WHEN is it possible?
// Create a loop for date range
$daterange = [];
for ($day = $search_from; $day <= $search_to; $day++) {
$daterange[]['date'] = $this->carbon->parse($day)->format('M d');
}
// Search Student
$students = User::has('userStudentAttendance')->with(['userStudentAttendance' => function($query) use ($details,$search_from, $search_to){
$query->where('status', $details);
$query->where(function($query) use ($search_from, $search_to){
$query->whereBetween(DB::raw('Date(created_at)'), [$search_from, $search_to]);
});
$query->groupby('user_id')->groupby(DB::raw('Date(created_at)'));
}])
->leftjoin('sys_user_student', 'sys_user_student.user_id', '=', 'sys_user.user_id')
->leftjoin('sys_mf_section', 'sys_mf_section.section_id', '=', 'sys_user_student.section_id')
->leftjoin('sys_mf_grade', 'sys_mf_grade.grade_id', '=', 'sys_mf_section.grade_id')
->where('user_type_id', '4')
->where('sys_mf_section.section_id', $request->getParam('section_id'))
->where('sys_mf_grade.grade_id', $request->getParam('grade_id'))
->orderBy('sys_user.last_name')
->get();
This is the look of the report that i want to achieve:
+--------------------------------------------------+
|student ID|full Name|Oct 23|Oct 24|Oct 25 | Oct 26|
|1 |stud 1 | P | P | P | A |
|2 |stud 2 | P | A | P | P |
|3 |stud 3 | P | P | P | P |
|4 |stud 4 | P | P | P | A |
|5 |stud 5 | A | A | A | A |
+--------------------------------------------------+

I guess you are using Laravel. Maybe you could use select raw query provided by Laravel.
->select('users.id AS user_id', 'users.name',
DB::raw('(CASE WHEN users.status = 0
THEN "active" WHEN users.status = 1
THEN "not active"
ELSE "pending" END) AS
status_user'))
->orderBy('shares.created_at', 'desc')

Related

where column = NULL and whereNotIn not working together in laravel

My code not working together, but if i only use one of them->where('numbers.client_group_id', NULL) OR ->whereNotIn('id', function($query) use ($request){ itu work normal.
$model = DB::table('numbers')->select('id','phone');
$model
->where('numbers.client_group_id', NULL)
->whereNotIn('id', function($query) use ($request){
$query->select('number_push_logs.number_id')->from('number_push_logs')->where('number_push_logs.client_group_id',$request->client_group);
})
->orderBy('quality', 'asc')->limit($request->total_push);
this my table looks like:
numbers table
| id| phone | client_group_id|
|---|------------|----------------|
| 1 |0852176255**| 1 |
| 2 |0852176255**| 1 |
| 3 |0852176255**| NULL |
number_push_logs table
| id| number_id |client_group_id |
|---|------------|----------------|
| 1 |1 | 1 |
| 2 |1 | 2 |
| 3 |2 | 2 |
so i want to select numbers data where client_group_id = NULL and id numbers not in number_push_log table with specific client_group_id
Try something like this. Use join. It performs better than nested demand.
\DB::table('numbers as n')
->select('id','phone')
->leftJoin('number_push_logs as npl', 'n.client_group_id', '=', 'npl.client_group_id')
->whereNull('npl.id')
->orderBy('quality', 'asc')
->limit($request->total_push);

Combine whereRaw() with leftjoin() using eloquent

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.*']);

How can we use count() with conditional sql in select() of laravel?

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();

Laravel join with LIKE CONCAT

Laravel 5.1.11
I have a simple search in my shop:
public function search($request $request)
{
return Catalog::where('title', 'like', '%'.$request->searchQuery.'%')
->orderBy('id', 'desc')
->paginate(50);
}
This is worked!
But people are looking for goods so: Pump BOSCH. And search result is null.
Because I changed my select:
public function search($request $request)
{
$searchQ = preg_split('/\s+/', $request->searchQuery, -1, PREG_SPLIT_NO_EMPTY);
return Catalog::where(function ($q) use ($searchQ) {
foreach ($searchQ as $value) {
$q->orWhere('title', 'like', "%{$value}%");
}
})
->orderBy('id', 'desc')
->paginate(50);
}
And this is worked), and show all Pumps!
But i want show only one Pump bosch.
My DB table manufactories:
| id | title |
| :--: | :----- |
| 1 | AlKO |
| 2 | BOSCH |
AND catalogs, where m_id is id from table manufactory:
| id | m_id | title | url |
| :--: | :---: | :---- | :--------- |
| 1 | 1 | pump | pump-alko |
| 2 | 2 | pump | pump-bosch |
How do I change the MySQL search query (adding LEFT JOIN and CONCAT) to find Pump bosch?
To make it look like this: CONCAT('catalogs.title', ' ', 'manufactories.title') LIKE '%'.$request->searchQuery.'%'
You can do simply like this,
$data = DB::table('manufactories')
->join('catalogs','manufactories.id','=','catalogs.m_id')
->select('manufactories.title','catalogs.title')
->where(DB::raw('CONCAT(manufactories.title," ",catalogs.title)'), 'like',"%{$value}%")
->get();
I hope it helps,
You can use the Query Builder to do joins e.g.
DB::table('catalogs')
->select('catalogs.*')
->join('manufactories', 'catalogs.m_id', '=', 'manufactories.id', 'left')
->where(function($q) use ($searchQ) {
foreach ($searchQ as $value) {
$q->orWhere('manufactories.title', 'like', "%{$value}%");
$q->orWhere('catalogs.title', 'like', "%{$value}%");
}
})
->get();

Eloquent query where column is in another table

I have two tables, posts and likes. I need to create a query, using Eloquent, that gets all posts that have been liked by a specific user_id.
In other words, it should be something like this:
SELECT * FROM posts p LEFT JOIN likes l ON p.id = l.post_id WHERE l.user_id = 2 ORDER BY l.created_at DESC
posts table:
+----+---------+------------+-------------+
| id | user_id | message | created_at |
+----+---------+------------+-------------+
| 1 | 2 | Hello! | <SOME TIME> |
| 2 | 3 | World! | <SOME TIME> |
| 3 | 2 | Something. | <SOME TIME> |
| 4 | 2 | Another. | <SOME TIME> |
+----+---------+------------+-------------+
likes table:
+----+---------+---------+-------------+
| id | post_id | user_id | created_at |
+----+---------+---------+-------------+
| 1 | 1 | 2 | <SOME TIME> |
| 2 | 2 | 2 | <SOME TIME> |
| 3 | 1 | 3 | <SOME TIME> |
| 4 | 3 | 2 | <SOME TIME> |
+----+---------+---------+-------------+
Here is my Postclass:
<?php
class Post extends Eloquent {
protected $table = 'posts';
public function likes()
{
return $this->hasMany('Like');
}
}
And the Like class:
<?php
class Like extends Eloquent {
protected $table = 'likes';
public function post()
{
return $this->belongsTo('Post');
}
}
How can I do this?
This should work:
$userId = //however you get the userid here.
$posts = Post::whereHas('likes', function ($q) use ($userId) {
$q->where('user_id', $user_id);
})->get();
You can use Laravel's DB class to perform joins on two or more tables, following is how your query will be executed in laravel:
$users = DB::table('posts')
->leftJoin('likes', 'posts.id', '=', 'likes.post_id')
->select('posts.*', 'likes.*')
->where('likes.user_id', '=', '2')
->orderBy('likes.created_at', 'desc')
->get();
Don't forget to use DB class on the top of your controller;
If you want to do it with eloquent, you should do the follwing:
$result = Post::whereHas('likes', function ($q) use($user_id)
{
$q->where('user_id', $user_id);
})
->orderBy('likes.created_at')
->get();

Categories