Nested Query in laravel - mysql

I have two tables:
Table 1: tbluser
ID Name
1 .......... name1
2 .......... name2
3 .......... name3
Another table that links tbluser and tblrole
Table2: tbllinkuserrole
userid..........roleid
1 ............2
1 .......... 2
1 .......... 2
2 .......... 2
3 .......... 1
I would like to fetch the tbluser.Name and the user role from tbllinkuserrole in to a table: a single table row(user record) can have multiple rows inside the column 'role' based on the roles fetched from tbllinkuser role. A user can have multiple roles.
can you help me out...

Laravel have Models (Eloquent), in the model class are some functions that are easy to user to fetch data from table. (this works with Laravel 5.2)
The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table. Models allow you to query for data in your tables, as well as insert new records into the table. https://laravel.com/docs/5.2/eloquent
So first of all, you need a User model (php artisan make:model User). You need to link the User modal to the right table.
//File: /laravel/app/User.php
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $table = 'tbluser';
public function userRoles() {
//Get the table data with the user roles
$this->hasMany('App\UserRoles', 'user_id', 'id');
//First argument gets the UserRoles Modal
//Second argument get the UserRoles column 'user_id'
//Third argument get the User table - column id
}
//File: /laravel/app/UserRoles.php
use Illuminate\Database\Eloquent\Model;
class UserRoles extends Model
{
protected $table = 'tbllinkuserrole';
public function rank() {
//Get the table data with role
$this->hasOne('App\Roles', 'id', 'role_id');
//First argument gets the Roles Modal (table)
//Second argument get the Roles column 'id'
//Third argument get the UserRoles modal (table) - column role_id
}
//File: /laravel/app/Roles.php
use Illuminate\Database\Eloquent\Model;
class Roles extends Model
{
protected $table = 'tblroles';
}
Now if you call Auth::user()->userRoles you will get an array with all rows from table that are linked to the current user.
And when you're running this you dump all the user rank data.
foreach(Auth::user()->userRoles as $userrole) {
{{ dump($userrole) }}
{{ dump($userrole->rank) }}
}
I hope this works for you!
More information can be found on https://laravel.com/docs/5.2/eloquent

TRY THIS ONE
SELECT tbllinkuserrole.userid, tbllinkuserrole.roleid, tbluser.name
FROM tbllinkuserrole, tbluser
WHERE tbllinkuserrole.userid = tbluser.id

The mysql to get the row values as column,
SELECT U.id, U.Name, MAX(CASE WHEN R.roleid = 1 THEN R.roleid END) role_1, MAX(CASE WHEN R.roleid = 2 THEN R.roleid END) role_2 from table_c AS U LEFT JOIN table_b AS R on (U.id = R.userid) WHERE 1 GROUP BY U.id

Related

Pivot table for single table in Laravel

I'm trying to add a multi-level categories in my website. where a category can have multiple child and also have multiple parent. It's look like many to many relationship in Laravel and I have to use a pivot table.
So that i create a table called categories and also a pivot table categories_reltionship like below. Now my question is how i will make this many to many relationship with this single table in Laravel.
categories table
==================
id title
=== ======
1 title_1
2 title_2
3 title_3
4 title_4
5 title_5
categories_relationship table
==================
parent_id child_id
========== ======
1 2
1 3
4 2
4 3
5 2
5 3
You can have methods like below on Category model :
//This will get you the list of categories
public function categories()
{
return ($this->hasManyThrough('App\Models\Category', 'App\Models\CategoryRelation', 'child_id', 'id', 'id', 'parent_id'));
}
//This will get you the list of children
public function childs()
{
return ($this->hasManyThrough('App\Models\Category', 'App\Models\CategoryRelation', 'parent_id', 'id', 'id', 'child_id'));
}
on CategoryRelation model :
class CategoryRelation extends Model
{
protected $table = 'categories_relationship';
}
I hope this will help you to solve your problem
Note : I suggest you to have 3 tables for many to many relationships,
in many to many relationship you should to have three tables. I hope that help you below example.
in our scenario as mentioned we have three tables with user , role and pivot names that each user can many roles and each role independent to many users.
user table have my_user_id(optional name) and other need column.
role table to have my_role_id (optional name) and other.
pivot table includes my_user_id , my_role_id.
in User model your codes should like below:
class User extends Model
{
public function roles()
{
return $this->belongsToMany('App\Role', 'pivot', 'my_user_id', 'my_role_id');
}
}
in Role model your codes should like below:
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\User', 'pivot', 'my_role_id', 'my_user_id');
}
}
You can also refer to laravel official documentation:
many to many relationships

fetching data from three tables in laravel

The is the table structure,which basically has three tables,namely expenses,categories and sunbcategories
table expenses
(id,category_id,sub_category_id,date,description,amount)
table categories
(id,category_name)
table subcategories
(id,sub_category_name,category_id)
This is the SQL query that is needed
select expense.date, expense.description, expense.amount,
category.category_name, subcategory.sub_category_name
from expenses as expense,categories as category,subcategories as subcategory
where expense.category_id=category.id and
category.id=subcategory.category_id);
This is the function in Expense model with which I pass the category_id
The same query mentioned above is written in laravel, but I am not able to
fetch the data.
function fetchExpenseData($categoryId)
{
$expense = Expense::select("expenses.*","categories.category_name as
Categoryname","subcategories.Sub_category_name")
->join("categories","categories.id","=","expenses.category_id");
->join("subcategories",function($join)
{
$join>on("subcategories.category_id","=","expenses.category_id")
->on("suncategories.id","=","expenses.sub_category_id")
})->get();
return $expenses;
}
$expenses that are returned will be printed in blade.php.
Can I know what is the mistake
thanks in advance
Hye there ,
You need to add eloquent model for retrieving data fromenter code here three tables
Like
I have School Table , Student Table , Teacher Table
School is relating with both Student and Teacher then we will add relationship
In School Model
`
public function getStudent(){
return $this->hasMany('student_id' , App\Student);
}
public function getTeachers(){
return $this->hasMany('teacher_id' , App\Teacher);
}
In Student table
public function getSchool(){
return $this->hasOne('school_id' , App\School);
}
`
now call data from student
`
$students = Student::with('getSchool.getTeachers')->get()
This Demonstration for what I have get from your Question

How to fetch records from two different tables in laravel5.2

I have two tables 'approval' and 'renewal', both having a common column 'applicant_id'.
When new application comes-in, it stores a data-record in table 'approval' alongwith the 'applicant_id' for whom the record has been added.
Now, when there is a renew applied for that same applicant, the row gets created in the table 'renewal' referencing the 'applicant_id'
Note: There can be a single record in the table 'approval' for a 'applicant_id' but there can be more than one record for the same 'applicant_id' in the table 'renewal'.
Now, my requirement is:
I need to fetch the records from both the table for all the applicants.
Conditions: If there is a data for the 'applicant_id' in both the table and 'renewal' table has multiple row for the same 'applicant_id', then I need to get the records from 'renewal' table only that too the latest one.
If there is no data in 'renewal' table but exists in 'approval' table for the 'applicant_id', then the fetch record should get the data present in 'approval' table.
Basically, if there is record for the applicant in 'renewal' table, get the latest one from there, if there is record present only in 'approval' table, then get that one but the preference should be to get from 'renewal' if exists.
I am trying to do this in laravel 5.2. So, is there anyone who can help me in this?
If you're using Eloquent, you'll have 2 models:
Renewal.php
<?php
namespace App;
use Illuminate\Eloquent\Model;
class Renewal extends Model
{
protected $table = 'renewal';
public static function findMostRecentByApplicantId($applicantId)
{
$applicant = self::where('applicant_id', '=', $applicantId)
->orderBy('date_created', 'desc')
->first();
return $applicant;
}
}
Approval.php
<?php
namespace App;
use Illuminate\Eloquent\Model;
class Approval extends Model
{
protected $table = 'approval';
public static function findByApplicantId($applicantId)
{
$applicant = self::where('applicant_id', '=', $applicantId)
->first();
return $applicant;
}
}
Then, in the code where you want to get the approval/renewal record, use the following code:
if (! $record = Renewal::findMostRecentByApplicantId($applicantId)) {
$record = Approval::findByApplicantId($applicantId);
}
//$record will now either contain a valid record (approval or renewal)
//or will be NULL if no record exists for the specified $applicantId
After few try, I got one way to do it using raw:
SELECT applicant_id, applicant_name, applicant_email, applicant_phone, renewed, updated_at
FROM (
SELECT renewal_informations.applicant_id, renewal_informations.applicant_name, renewal_informations.applicant_email, renewal_informations.applicant_phone, renewal_informations.renewed, renewal_informations.updated_at
FROM renewal_informations
UNION ALL
SELECT approval_informations.applicant_id, approval_informations.applicant_name, approval_informations.applicant_email, approval_informations.applicant_phone, approval_informations.renewed, approval_informations.updated_at
FROM approval_informations
) result
GROUP BY applicant_id
ORDER BY applicant_id ASC, updated_at DESC;
For every single Approval id, there can b multiple records for renewal table suggests you have One to Many relation. which you can define in the your Model like
Approval.php (App\Models\Approval)
public function renewal()
{
return $this->hasMany('App\Models\Renewal', 'applicant_id')
}
Having defined this relation. you can get the records from the table using applicant_id.
$renewal_request_records = Approval::find($applicant_id)->renewal();
This will get all records from renewal table against that applicant_id.
Finding the latest
$latest = Renewal::orderBy('desc', 'renewal_id')->first();
Further Readings Eloquent Relations

Laravel Eloquent ManyToMany getLatest

I built up a pivot table containing ids of tables I want to associate. When I have the id of a specific item, I now want to get the latest entry of this item saved in the pivot table. For example:
Table 1: Tickets
Table 2: Status
Table 3: Ticket_Status (Pivot)
If I add a new entry to the pivot table, I would have something like this:
Pivot
ticketId, statusId
1, 2
1, 3
2, 1
Now I want to receive the latest status in the pivot for Ticket Id 1 for example, so I expect to receive statusId 3 for ticket 1. But how do I do this in Laravel?
Creating the entries for the pivot table works:
public function attachDispatchStatus($id) {
$this->status()->attach($id);
$this->touch();
}
// set fields on the eloquent object and save to database
// raise event that the incident was created.
public function createDispatch($command) {
// Get BodyContent from POST Request
$this->dispatchReference = $command->dispatchReference;
$this->incidentReference = $command->incidentReference;
// Create new Dispatch
$dispatch = Dispatch::create(array(
'dispatch_reference' => $this->dispatchReference,
'incident_reference' => $this->incidentReference
));
$dispatchStatus = DispatchStatus::where('status', '=', 'processing')->first();
$dispatch->attachDispatchStatus($dispatchStatus->id);
return $this;
}
Why don't you use the updateExistingPivot($roleId, $attributes); available in Laravel 5 when editing your tickets ?
This will solve your problem and make your database lighter :)
Check Larvel Doc for some examples on pivot table.
If you don't want to make it like that (because you want to keep an historic of your input), I think you will have to add an dateTime field in your pivot table... Then, just order by date, and you will be fine.

Building an entity join LINQ query

I have the following table strutucture and am accessing them by using MySQL Entity Framework:
Table Users
- Id
- Name
Table Subscriptions
- Id
- Id_User
- Id_Course
Table Courses
- Id
- Name
What I would like and am having a hard time to do so is building a link query for all users that returns a list with each entry containing:
User Id;
User name;
Concat string separated by comma with all courses for the user or 'no courses' string if none.
This list should be filtered by a part of users name.
I've started to build the code but can't finish it:
var Model db = new Model();
var list = from user in db.Users
join ???
where user.Name.Contains(filter.Trim())
select new { Name = user.Name, Id = user.Id, ???}
Can anyone help me please ?
You should use navigation properties (like User.Subscriptions) for this. Depending on how you created the model they may already be there, else you first should add them.
var query = from u in db.Users
where user.Name.Contains(filter) // trim the filter value first
select new
{
u.Name,
u.Id,
Courses = u.Subscriptions.Select(s => s.Course.Name)
};
var result = query.AsEnumerable()
.Select(q => new
{
q.Name,
q.Id
Courses = string.Join(", ", q.Courses)
};
The reason for doing this in two phases is that string.Join can't directly be used in an EF LINQ expression (can't be turned into SQL) so it must be done in memory (i.e. after an AsEnumerable).
But still it may be efficient to do a projection first (the first part), otherwise too much data may be fetched from the database.