I'm trying to retrieve data from database to laravel blade view with join associate table.
in my case I have two tables called interesting_courses and courses. here some student can have many interesting courses. Therefore courses_id stored as json array in database as follows.
["1","11","15","16"]
but I need to join the courses table to get the associate course name as follows.
["Hospitality","Business Management","Auto Mobile","Health Care"]
Below is my controller
$intresting_courses = DB::table('intresting_courses')
->join('courses','courses.id','=','intresting_courses.courses_id')
->where('intresting_courses.youth_id',$id)
->first();
How can I join the tables.
There is no way you can join it in query natively.
The solution is to write two queries
select * from intresting_courses where youth_id = ? limit 1
select * from courses where id in (1, 2, 3, 4, 5, ...)
that way you can get courses that student intresting.
Here the laravel code for thoses queries.
$intresting_courses = DB::table('intresting_courses')
->where('intresting_courses.youth_id', $id)
->first();
$courses = DB::table('courses')
->whereIn('id', json_decode($intresting_courses->courses_id))
->get();
Related
I have four tables technologies(id, name), tasks(id, name), requests(id, status_id, comment, task_id, created_at), technology_task(id, task_id, technology_id)
I want to get the requests whose status_id is 2 and join the tasks table which has specific technologies inserted in the technology_task pivot table. I want to group the result based on the date column created_at. Is this possible through Lravel model eloquent? I have tried the below method.
$this->model
->with('task', 'task.technologies')
->where('status_id', 2)->get()
->groupBy(function ($val) {
return Carbon::parse($val->created_at)->format('d-m-Y')
This is the Request model and this will return all the requests whose status_id is 2 along with the related task and technologies. But I only want the requests whose task have specific technologies, and I want to check that using something like ->whereIn('id', [1, 2, 3])->get()
How to achieve this using model? or do I need to use a custom query
Assuming $this->model is your Request model, and all your relationships are set correclty, you can use whereHas:
$technologyIds = [1, 2, 3];
$collection = $this->model
->with(['task', 'task.technologies'])
->whereHas('task.technologies', function($query) use ($technologyIds)
{
// here you can check using whereIn
$query->whereIn('technologies.id', $technologyIds);
})
->where('requests.status_id', 2)
->get();
If you want to use the groupBy inside the MySQL query, you will need to define what data should MySQL select when grouping. You can achieve that using aggregation functions. You weren't clear about the data you want to select, the code bellow should return:
the greatest id of the grouped rows,
unique comments concatenated with space
created_at
$technologyIds = [1, 2, 3];
$collection = $this->model
->with('task', 'task.technologies')
->whereHas('task.technologies', function($query) use ($technologyIds)
{
$query->whereIn('technologies.id', $technologyIds);
})
->where('requests.status_id', 2)
->groupBy('requests.created_at')
->selectRaw('
MAX(requests.id) AS id,
GROUP_CONCAT(DISTINCT requests.comment
ORDER BY requests.comment ASC SEPARATOR ' ') AS comments,
requests.created_at
')
->get();
Check out the docs to see how each aggregation functions works.
i have a piece of code that is supposed to join two tables Enumerator Data and export the result. Here is the controller code for handling that.
$joinTableName = (new Enumerator())->getTable();
$fromTableName = (new FarmData())->getTable();
$selectedColumns = [
"{$fromTableName}.first_name",
"{$fromTableName}.middle_name",
"{$fromTableName}.last_name",
"{$fromTableName}.farm_phone_number",
"{$fromTableName}.age",
"{$fromTableName}.farmer_bvn",
"{$joinTableName}.state",
"{$joinTableName}.lga",
"{$fromTableName}.enum_unique_id"
];
$v2_farm_data = FarmData::whereNotNull('enum_unique_id')->select($selectedColumns)
->leftJoin(
$joinTableName,
"{$joinTableName}.unique_id",
'=',
"{$fromTableName }.enum_unique_id"
)
->get();
The resulting csv data has some empty state and lga fields. I presume it has to do with the fact that the Enumerator table has about 20,000 records while the Data table has about 100,000 records. Using just a join statement returns data records of just 20,000. I want to get all the data records which are about 100,000. What am i doing wrong?
I'm trying to use Laravel Query Builder to join 2 tables.
Here's my query for joining 2 tables
$instructors = DB::table('instructors')
->join('instructor_courses', 'instructors.id', '=','instructor_courses.instructor_id')
->where('instructor_courses.course_id', $schedule->course_id)
->where('instructor_courses.position', 'Instructor')
->whereNull('instructor_courses.deleted_at')
->whereNull('instructors.deleted_at')
->get();
The code let me join the table properly however this results to multiple duplication. Take a look at the result passed in select tag
Here's the schema I have
Instructor Table
Instructor Courses Table
Basically what I want to achieve is to display a record without duplication. Is there a better approach in joining multiple table like this one? Thank you
You should use groupBy for instructors.id
$instructors = DB::table('instructors')
->join('instructor_courses', 'instructors.id', '=','instructor_courses.instructor_id')
->where('instructor_courses.course_id', $schedule->course_id)
->where('instructor_courses.position', 'Instructor')
->whereNull('instructor_courses.deleted_at')
->whereNull('instructors.deleted_at')
->groupBy('instructors.id') //add a line
->get();
Try to use the ->distinct() function in laravel to prevent duplicates in selecting data.
$instructors = DB::table('instructors')
->join('instructor_courses', 'instructors.id', '=','instructor_courses.instructor_id')
->where('instructor_courses.course_id', $schedule->course_id)
->where('instructor_courses.position', 'Instructor')
->whereNull('instructor_courses.deleted_at')
->whereNull('instructors.deleted_at')
->groupBy('instructors.id')
->distinct()
->get();
I'm using luman and Database Query Builder to fetch full user info from database.
First, Please Take a lock at my database structure:
I have a table called users and a series of other tables that are related to user groups (Ex: secretaries, patients, doctors and admins) which stores additional information about the users.
Also To determine user access, I have a level column on user table which can have one of this value as enum: 'admin', 'doctor', 'secretary', 'patient'.
So, I want to get this information using one query by join and select.
My training code is something like this:
$userInfo = User::where("userID", $userID)
->limit(1)
->join('[GROUP_TABLE_NAME]', function ($join) {
$join->on('user.userID', '=', '[GROUP_TABLE_NAME]' .'.'.
'[GROUP_NAME]' . 'ID');
})
->get();
The GROUP_NAME comes from level column on user table and the GROUP_TABLE_NAME can be built based on the GROUP_NAME value(Ex: ['secretary' => 'secretaries' , 'patient' => 'patients' , ...]).
Any idea to handle the join structure using laravel query builder?
First you should be aware of the fact that this code architecture is not convenient and not easy to understand for other developers.
SQL
You can achieve your goal by using union and join.
Just convert this query for laravel builder or use it directly with DB::statement: select users.*, infos.info from users left join (( select secretaries.* from secretaries ) UNION (select doctors.* from doctors)) infos ON users.id = infos.user_id where users.id=?.
But
The easiest way to do it is to fetch info in two queries, both indexed and fast: user from users by primary key and then info by indexed field user_id in it. Create Doctorinfo, Admininfo models and correspondent migrations. So user class can be smth like this:
public function getInfo() {
switch($this->level) {
'doctor':
return $this->doctorinfo;
...
}
}
private function doctorinfo() {
$this->hasOne('App\Doctorinfo');
}
Builder
You can use left join to join all sub tables as well. The following builder selects info column.
User::where("userID", $userID)->limit(1)
->leftJoin('patients', 'users.id', '=', 'patients.user_id')
->leftJoin('doctors', 'users.id', '=', 'doctors.user_id')
->leftJoin('admins', 'users.id', '=', 'admins.user_id')
->select('users.*', DB::raw('IF(users.level="admin", admins.info, (IF users.level="doctors", doctors.info, patients.info))'))
I am setting 1 row per page in symfony pager but its showing more data than 1. It is because my query is left joining the sfGuardUser table with other tables and it is causing duplication of 'sfGuardUser' row in some cases when there are multiple entries in 'license' table for that particular user ! Here is my query:
$pager = new sfDoctrinePager('sfGuardUser', '1');
$q = Doctrine_Query::create()
->select('u.id, u.username, g.name, l.id, l.status, l.client_id, l.vendor_id, l.applied_date, p.org_name')
->from('sfGuardUser u')
->leftJoin('u.Profile p')
->leftJoin('u.Groups g')
->leftJoin('u.LicensedClients l')
->where('g.name = \'vendor\'')
->orderBy('l.applied_date');
$q->setHydrationMode(Doctrine_Core::HYDRATE_SCALAR);
$pager->setQuery($q);
$pager->setPage($request->getParameter('page', 1));
$pager->init();
The pagination is there, but problem is in some cases there are multiple rows shown in one page when there are multiple rows for a particular user in the license table. How can I implement it in a right way ?
What do you want to achieve with joining user and license table (1:n relation) when paging through (sfGuard)Users ?
If you want to sort users by license type/date/count, you could use
DISTINCT u.id, u.username