convert sql query (join) in laravel query builder - mysql

I want to do this request with laravel ( i have 3 tables users , userprojet and projets ) users hasmany projets and projet hasmany users that's why i do another table userprojet to join the two table
and now i try to extract the projet of a specific user with this request
select projets.*
from projets p
, userprojet up
, users u
where p.id= up.projet_id
and up.user_id = u.id
and user_id = 2;
I need help please.

You can try this:
$users = DB::table('projets')
->join('userprojet', 'projet_id.id', '=', 'userprojet.projet_id')
->join('userprojet', 'users.id', '=', 'userprojet.user_id')
->select('project.*')
->where('userprojet.user_id', 2)
->get();
References:
Laravel -> Queries -> Joins

You can also define many to many relationship in your models instead of writing queries every time
// User model
public function projets()
{
return $this->belongsToMany(Projet::class, 'userprojet');
}
// Projet model
public function users()
{
return $this->belongsToMany(User::class, 'userprojet');
}
// in controller
$user = User::first(); // for example
dd($user->projets);
// with eager loading
$user = User::with('projets')->first();
dd($user->projets);

Related

Need to convert a query into Eloquent Model laravel

I have a query of MySQL but I need to convert it into an eloquent model laravel 8. The query is given below,
$query = "SELECT group_id FROM `chat_histories` join chat_group on chat_group.id = chat_histories.group_id where chat_group.is_group = 1 and chat_histories.created_at BETWEEN '$startDate' and '$endDate' and chat_histories.deleted_at is null group by group_id";
$query = "select count(group_id) as total_chat_thread from ($query) total_chat";
DB::select($query);
So far i have done this,
ChatHistory::leftJoin('chat_group', 'chat_group.id', '=', 'chat_histories.group_id')
->selectRaw('count(*) as totals')
->where('chat_group.is_group', 1)
->whereBetween('chat_histories.created_at', [$startDate, $endDate])
->groupBy('chat_histories.group_id')
->count('totals');
But this returns a list, but I need that count of the list. That means it's showing 22 rows, I need that 22 as return.
My Model ChatHistory relation with ChatGroup
public function chatGroup() {
return $this->belongsTo(ChatGroup::class, 'group_id', 'id');
}
My Model ChatGroup relation with ChatHistory
public function chatHistory() {
return $this->hasMany(ChatHistory::class,'group_id','id');
}
Please help to convert it into an eloquent model query
Thanks in advance.
If you have the model Group with a relation history hasMany. it should be like this.
$groupCount = ChatGroup::whereHas('chatHistory', function ($historyQB) use($startDate,$endDate) {
$historyQB->whereBetween('created_at', [$startDate, $endDate])
->whereNull('deleted_at');
})->count();
You dont need the whereNull, if the model ChatHistory has softDelete enabled.
Maybe you should consider using Models, it would be much easier/cleaner
Something like that should work
DB::table('chat_histories')->select('group_id')->join('chat_group', 'chat_group.id', 'chat_histories.group_id')->where('chat_groups.is_group', 1)->whereBetween('chat_histories.created_at', $startDate, $endDate)->whereNull('chat_histories.deleted_at')->groupBy('group_id')->count();

Write Eloquent queries in raw mysql

I want to know how can I write These two Eloquent Queries into raw SQL? also Is there a way to convert the Eloquent series into raw SQL series so that I could use those?
public function items()
{
return $this->belongsToMany(Product::class, 'order_items', 'order_id', 'product_id')->withPivot('quantity', 'price');
}
public function user()
{
return $this->belongsTo(User::class);
}
If we talk about the first query used in the items method. After changing it into raw SQL it will become
DB::select('select `products`.*, `order_items`.`order_id` as `pivot_order_id`, `order_items`.`product_id` as `pivot_product_id`, `order_items`.`quantity` as `pivot_quantity`, `order_items`.`price` as `pivot_price` from `products` inner join `order_items` on `products`.`id` = `order_items`.`product_id` where `order_items`.`order_id` = `order_id`');
and the second query inside the user method will become
DB::select('select * from `users` where `users`.`id` = `id`');

Compare two fields within different table using Laravel

I have two tables employees and customers , i've gave the schema below.
Customers('id' , 'username', 'location');
Employees('id' , 'EmployeeID' , 'CustomerID', 'location');
Currently I can use a query to retrieve customers details like the below query , note this is when the user is logged into the system hence the Auth::
$customerQuery1 = DB::table('customer')
->where('id', '!=', Auth::id())
->where('item', '=' , Auth::customer()->recommendation)
->get();
Each Employee has many customers ,I want other customers to see other customer items so i have attach the CustomerID field which is a foreign key and relates to the id field within the Customer table.
I've tried something like the below however I think I may need a join query but i'm unsure.
$query2 = DB::table('Customer','Employee')
->select('username')
->where(['EmployeeID' => Auth::id(), 'CustomerID' => 'id'])
->get();
$query2 = DB::table('Customer')
->select('username')
->join('Employee', 'Customer.id', '=', 'Employee.CustomerID')
->where(['EmployeeID' => Auth::id(), 'CustomerID' => 'id'])
->get();
I am then returning the values to my blade file like the below
return view ('pages.dashboard')
->with('query1',$query1)
and then Im using php indentation within my blade file to return the users data
#foreach ($query1 as $Userfound)
{{ $Userfound->username}}</p>
#endforeach
Actual Query needed in plain english
so I need to select a customer , where CustomerID == id
NOTE: id is from the customers table, CustomerID stored in the Employees table.
You can create Models using Laravel, for example:
Employee.php
public function customers()
{
return $this->hasMany('App\Customer');
}
Customer.php
public function employee()
{
return $this->belongsTo('App\Employee');
}
Which you can access like so:
$customer = Customer::where('id',Auth::user()->id)->firstOrFail();
or
$employee = Employee::where('id',Auth::user()->id)->firstOrFail();
And to see an employee's customers:
$employee->customers()->get();
Or to see the other customers of $customer's employer:
$customer->employee()->customers()->get();

Where not Exists en Laravel

Could anybody tell me what error I might have in my laravel query, basically what I want is to list the records of a table whose id is not related in another table. I did it in Mysql with this query: SELECT * FROM item WHERE NOT EXISTS (SELECT null FROM qualifications WHERE grades.item_id = item.id AND qualifications.user_id = 2);
but now I need to do this same query in laravel, I tried it this way:
codigo
and what I get is this syntax error that I do not know how to solve anymore:
error
I am very grateful to anyone who can tell me what I am doing wrong, or in what form I make that query in Laravel.
You can also rewrite your query as left join like
SELECT i.*
FROM item i
LEFT JOIN qualifications q ON q.item_id = i.id AND q.user_id = 2
WHERE q.item_id IS NULL
In query builder you can write it as
DB::table('item as i')
->select('i.*')
->leftJoin('qualifications as q', function ($join) use($user_id) {
$join->on('q.item_id', '=', 'i.id')
->on('q.user_id', '=', $user_id);
})
->whereNull('q.item_id')
->get();
Another approach which i suggest you to go with, is setup your relations and models and do it with eloquent way
class Item extends Model
{
public function qualifications()
{
return $this->hasMany(\App\Models\Qualification::class, 'item_id');
}
}
class Qualification extends Model
{
public function qualifications()
{
return $this->belongsTo(Item::class, 'item_id');
}
}
And then you can use Querying Relationship Absence
Item::whereDoesntHave('qualifications', function ($query) use($user_id) {
$query->where('user_id', '=', $user_id);
})->get();

Joins in laravel 5.3 in simple and Eloquent

I want to add some extra filter in my left join but I don't know how so kindly help me.And also tell me how can make this query in Eloquent. My query is given below:
select * from `users`
join `halls` on `halls`.`user_id` = `users`.`id`
left join `bookings` on `bookings`.`hall_id` = `halls`.`id` AND month(`bookings`.`date`) = 2 and day(`bookings`.`date`) = 4 and year(`bookings`.`date`) = 2017
join `user_role` on `user_role`.`user_id` = `users`.`id`
join `roles` on `roles`.`id` = `user_role`.`role_id`
where
`roles`.`id` = 2 AND
(`bookings`.`id` is null OR `bookings`.`status` = 0 )
group by users.id
user and role has many to many relation, user and hall one to many and hall and bookings has also one to many relation
User Model Relation
/**
* Many-to-Many relations with Role.
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function roles(){
return $this->belongsToMany(Role::class, 'user_role', 'user_id', 'role_id')->select('roles.name');
}
/**
* One-to-Many relations with halls.
*
* #return \Illuminate\Database\Eloquent\Relations\hasMany
*/
public function halls(){
return $this->hasMany(Hall::class);
}
Hall Model relation
public function user(){
return $this->belongsTo(User::class, 'user_id', 'id');
}
public function bookings(){
return $this->hasMany(Booking::class);
}
Booking Model Realtion
public function hall(){
return $this->belongsTo(Hall::class)->distinct();
}
I dont know why you want to use group by without any aggregate function . Your ORM looks like below
Users::join('halls', 'users.id', '=', 'halls.user_id')
leftJoin('bookings', function($join){
$join->on('halls.id', '=', 'bookings.hall_id');
$join->on(DB::raw('month(`bookings`.`date`) = 2 and day(`bookings`.`date`) = 4 and year(`bookings`.`date`) = 2017'));
})
->join('user_role', 'users.id', '=', 'user_role.user_id')
->join('roles', 'roles.id', '=', 'user_role.role_id')
->whereRaw('where
`roles`.`id` = 2 AND
(`bookings`.`id` is null OR `bookings`.`status` = 0 )')->get();