How to write a Laravel query to group duplicate records - mysql

This is my current query getting data from tables corporations, jobs, corp_networks and candidates.
$sqlCandSkills = DB::table('corporations')
->join('jobs', 'corporations.corp_id', '=', 'jobs.corp_id')
->join('corp_logos', 'corp_logos.corp_id', '=', 'corporations.corp_id')
->join('candidates', 'corporations.corp_id', '=', 'candidates.corp_id')
->join('corp_networks', 'corporations.corp_id', '=', 'corp_networks.participation_corp_id')
->where([
'corp_networks.owning_corp_id' => $this->corp->corp_id,
'corp_networks.status' => "Accepted"
])
->orwhere([
'corporations.corp_id' => $this->corp->corp_id
])
->where('candidates.is_available', '=', 0)->get();
I need to add a validation query into this because I'm getting multiple rows of same data from above query.
for($i=0 ; $i<sizeof($skillsArray); $i++){
$value= $skillsArray[$i];
echo($value);
$jobDetails = DB::select(
'SELECT * FROM jobs WHERE job_technical_requirements LIKE "%'.$value.'%" AND job_status = 1 INNER JOIN '
);
}
Above query gives all data but I also need to perform above checks.
I'm doing this second query to compare array of values to a csv values in column.
Now I need to achieve all this into a single result.
I need ways to do it either in sql query or laravel query.

you can use groupBy
$sqlCandSkills = DB::table('corporations')
->distinct()
->join('candidates', 'corporations.corp_id', '=', 'candidates.corp_id')
->join('corp_networks', 'corporations.corp_id', '=', 'corp_networks.participation_corp_id')
->where([
'corp_networks.owning_corp_id' => $this->corp->corp_id,
'corp_networks.status' => "Accepted"
])
->orwhere([
'corporations.corp_id' => $this->corp->corp_id
])
->where('candidates.is_available', '=', 0)
->groupBy(array(
'corporations.corp_id',
'corp_networks.participation_corp_id',
'corp_networks.owning_corp_id'
))
->get('corporations.corp_id');

Related

MySql group by with where condition not working

I have 2 tables, groups and questions. I need the result in such a way that it contains group name and corresponding non-deleted question count.
The structure and data for the two tables are as afollows.
My expected Result is as follows
I tried the following code, but it gives the entire row including the deleted questions.
$groupname = DB::table('groups as d')
->select([
'd.id','d.group_name',DB::raw("count(dtls.survey_group_id) as count")
])
->leftJoin('questions as dtls','d.id', '=', 'dtls.survey_group_id')
->whereNotExists( function ($query) {
$query->select(DB::raw(1))
->from('questions')
->where('id', 'd.id')
->where('dtls.is_deleted', 1);
})
->groupBy('d.id','d.group_name')
->get()
->toArray();
A problem here is that ->where('id', 'd.id') mathches id with the literal string d.id which obviously is not what you want. In addition, inner query tables should be aliased to prevent ambiguity. You can try changing it to:
$groupname = DB::table('groups as d')
->select([
'd.id','d.group_name',DB::raw("count(dtls.survey_group_id) as count")
])
->leftJoin('questions as dtls','d.id', '=', 'dtls.survey_group_id')
->whereNotExists( function ($query) {
$query->select(DB::raw(1))
->from('questions as innerDtls')
->whereRaw('innerDtls.id = d.id')
->where('dtls.is_deleted', 1);
})
->groupBy('d.id','d.group_name')
->get()
->toArray();
Alternatively your current query can be simplified to:
$groupname = DB::table('groups as d')
->select([
'd.id','d.group_name',DB::raw("count(dtls.survey_group_id) as count")
])
->leftJoin('questions as dtls','d.id', '=', 'dtls.survey_group_id')
->where('dtls.is_deleted', 0)
->groupBy('d.id','d.group_name')
->get()
->toArray();

laravel query building with a lot of joins

my sql query is
$q = "SELECT
file,
roleId,
page,
type,
userType,
COUNT(DISTINCT($a)) as 'a',
COUNT(DISTINCT($b)) as 'b'
FROM table_name
WHERE
course IN ($type)
AND date BETWEEN '$startDate' AND '$endDate'
AND (course_1 is NULL OR course_1 NOT IN ('ABCD'))
AND deleted IS NULL
AND type LIKE '%Professor%'
AND action = 'submit'
GROUP BY file, roleId";
I want to convert that query into laravel query builder like
$orders = DB::table('table_name')
->select('file', 'roleId', 'page', 'type', userType DB::raw('COUNT(DISTINCT(($a)) as 'a'))
->groupBy('file', 'roleId')
->get();
Do understand how to add the other COUNT into it and how and where to chain the ->where() ?
<?php
$orders = DB::table('table_name')
->whereIn('course', $courseTypes)
->whereBetween('date', [$startDate, $endDate])
->where(function($q){
return $q->whereNull('course_1')
->orWhereNotIn('course_1', $courseArrayToFilter);
})
->whereNull('deleted')
->where('type', 'like', '%Professor%')
->where('action', 'submit')
->groupBy('file', 'roleId')
->select(
'file',
'roleId',
'page',
'type',
'userType',
\DB::raw("COUNT(DISTINCT($a)) as a"),
\DB::raw("COUNT(DISTINCT($b) as b")
)
->get();
Maybe in a cleanest way doing this:
Use the Model instance in inspite of invoke the DB facade
Use whereRaw to pass complex or pure SQL queries
Use selectRaw() to process pure SQL queries for instance functions like COUNT
Use Multiple WHERE to emulate AND operator
Use whereIn to filter ranges of data
You need to GROUP BY all columns in your SELECT you have an error at this point, I mean your query is wrong
Code
$data = Model::select('file', 'roleId', 'page', 'type', 'userType')
->selectRaw('COUNT(DISTINCT($a)) as a')
->selectRaw('COUNT(DISTINCT($b)) as b')
->whereRaw('type IN $type')
->whereIn('date', [$startDate, $endDate])
->whereRaw("course_1 IS NULL OR course_1 NOT IN('ABCD')")
->whereNull('deleted')
->where('type', 'LIKE', "%".'Professor'."%")
->where('action', '=', 'submit')
->groupBy('file', 'roleId', 'page', 'type', 'userType')
->get();

Convert Raw SQL query to Laravel DB Query

I have the following raw SQL query:
select a.id user_id, a.email_address, a.name_first, a.name_last, count(b.id) number_of_videos, sum(b.vimeo_duration) total_duration, sum(b.count_watched) total_playbacks
from users a,
videos b
where a.id = b.tutor_id
and a.email_address in ('candace_rennie#yahoo.com', 'tjm#hiltoncollege.com', 'matthewjameshenshall#gmail.com', 'nkululeko#syafunda.co.za', 'khulile#syafunda.co.za', 'nzakheni#syafunda.co.za')
group by a.id;
This correctly gets 6 rows from the database. I'm trying to convert this to a Laravel database query like so:
$totals = DB::table('users')
->select(DB::Raw('users.id as user_id'), 'users.email_address', 'users.name_first', 'users.name_last', DB::Raw('count(videos.id) as number_of_videos'), DB::Raw('sum(videos.vimeo_duration) as total_duration'), DB::Raw('sum(videos.count_watched) as total_playbacks'))
->join('videos', 'users.id', '=', 'videos.tutor_id')
->where('users.id', 'videos.tutor_id')
->whereIn('users.email_address', array('candace_rennie#yahoo.com', 'tjm#hiltoncollege.com', 'matthewjameshenshall#gmail.com', 'nkululeko#syafunda.co.za', 'khulile#syafunda.co.za', 'nzakheni#syafunda.co.za'))
->groupBy('users.id')
->get();
This however return 0 rows. Is there anything I'm missing?
It should be smth like below even tho groupBy user id does not help much as id is unique.
$aggregates = [
DB::raw('count(b.id) as number_of_videos'),
DB::raw('sum(b.vimeo_duration) as total_duration'),
DB::raw('sum(b.count_watched) as total_playbacks'),
];
$simpleSelects = ['users.email_address', users.id, 'users.name_first', 'users.name_last'];
$emails = ['candace_rennie#yahoo.com', 'tjm#hiltoncollege.com'....]
$users = Users::select(array_merge($simpleSelects, $aggregates))
->leftJoin('videos as b', function ($join) use ($emails) {
$join->on('b.tutor_id', 'a.id')
->whereIn('users.email_address', $emails);
})
->groupBy('users.id')
->get();
Try to remove this line:
->where('users.id', 'videos.tutor_id')
List item
after sql code convert into laravel
DB::select('posts.id','posts.title','posts.body')
->from('posts')
->where('posts.author_id', '=', 1)
->orderBy('posts.published_at', 'DESC')
->limit(10)
->get();

Laravel count with where on Query Builder with joins

Good day all, I am trying to count all records in a table but only if the table does not contain data in a specific column (deleted_at). It is a join table the table names are companies and employees. I am currently counting the records with a DB::raw but it should only count it if the deleted_at column is null. Please understand that i am a beginner.
public function index()
{
$user = Auth::user()->id;
$companies = DB::table('companies AS c')
->select([
'c.id',
'c.logo',
'c.company_name',
'c.created_at',
'c.sector',
'c.deleted_at',
DB::raw('COUNT(e.id) AS employee_count')
])
->leftJoin('employees AS e', 'e.company_id', '=', 'c.id' )
->leftJoin('company_user AS cu', 'cu.company_id', '=', 'c.id')
->where('cu.user_id', '=', $user)
->where('c.deleted_at', '=', null)
->groupBy('c.id')
->get();
return view('account.companies.index')
->with('companies', $companies);
}
If you are using Mysql then you could use conditional aggregation
$companies = DB::table('companies AS c')
->select([
'c.id',
'c.logo',
'c.company_name',
'c.created_at',
'c.sector',
'c.deleted_at',
DB::raw('SUM(c.deleted_at IS NULL) AS employee_count')
])
->leftJoin('employees AS e', 'e.company_id', '=', 'c.id' )
->leftJoin('company_user AS cu', 'cu.company_id', '=', 'c.id')
->where('cu.user_id', '=', $user)
->groupBy('c.id')
->get();
In mysql when an expression is used inside sum(a= b) it will result as a boolean 0/1 so you can get your conditional count using above
Or you could use whereNull() method in your query
->whereNull('c.deleted_at')
Use this code:
$employeeCount = DB::table('employees')
->select('companies.name', DB::raw('count(employees.id) as employee_count'))
->join('companies', 'employees.company','=','companies.id')
->groupBy('companies.id')
->get();

Join 3 table with query builder in laravel

I have a 3 table questions,registrations,ssi_tracks i need to get details from the registraions table by corresponding to other two tables
i need to get details from registrations based on
questions.question_schedul=0 ,ssi_tracks.track_first_status
i have wrote query but it says the column is not found here is my query
$register = DB::table('registrations')
->join('questions', 'registrations.registration_id', '=', 'questions.question_id')
->join('ssi_tracks','registrations.registration_id','=','ssi_tracks.registration_id')
->select('address', 'model', 'chassis', 'delivery_date','ssi_tracks.track_first_status')
->where([["questions.question_schedul", "=", $dropselected] and ['ssi_tracks.track_first_status',0]])
->get();
Try this:
$register = DB::table('registrations as R')
->select('R.address', 'R.model', 'R.chassis', 'R.delivery_date','S.track_first_status')
->join('questions as Q', 'R.registration_id', '=', 'Q.question_id')
->join('ssi_tracks as S','R.registration_id','=','S.registration_id')
->where('Q.question_schedul', '=', $dropselected)
->where('S.track_first_status', '=', 0)
->get();
Make sure you have used the right column here from question table for matching registration id:
->join('questions as Q', 'R.registration_id', '=', 'Q.question_id')
try this query :
$register = DB::table('registrations')
->leftJoin('questions', 'registrations.registration_id', '=', 'questions.question_id')
->leftJoin('ssi_tracks','registrations.registration_id','=','ssi_tracks.registration_id')
->select('registrations.address', 'registrations.model', 'registrations.chassis', 'registrations.delivery_date','ssi_tracks.track_first_status')
->where(['questions.question_schedul'=>$dropselected,'ssi_tracks.track_first_status'=>0])
->get();