Covert SQL to Laravel Query Builder - sql

I'm a beginner regarding Laravel Query Builder, can you guys help me convert this SQL to Query Builder
public function check_available_room(Request $request, $checkin_date)
{
$available_rooms = DB::SELECT("SELECT * FROM rooms WHERE id NOT IN (SELECT room_id FROM bookings WHERE '$checkin_date' BETWEEN checkin_date AND checkout_date)");
}
Book model
function rooms() {
return $this->belongsTo(Room::class, 'room_id');
}
Room model
public function bookings() {
return $this->hasMany(Booking::class);
}
Thank you so much

Here is a solution if you have your models and relations in place
$availableRooms = Room::whereDoesntHave('bookings', function($bookingQuery) use ($checkin_date) {
$bookingQuery->where('checkin_date', '<', $checkin_date)
->where('checkout_date', '>=', $checkin_date);
})->get();

$unavailable_room_ids = Booking::where('checkin_date', '<', $checkin_date)
->where('checkout_date', '>=', $checkin_date)
->pluck('room_id')->get();
$available_rooms = Room::whereNotIn('id', $unavailable_room_ids)->get();

Related

Laravel 7 Eloquent models - (not being able to do where outside table) Unable to find column on businessDeveloper.user_id, select * from opportunities

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'businessDeveloper.user_id' in 'where clause' (SQL: select * from opportunities where businessDeveloper.user_id = 3)
Hello, I'm using Laravel 7 and eloquent models for a school project. We were told not to use joins and besides making a custom JSON string with the formatted data which will take a lot of work since I have the same problem for other functionalities as well. I got no clue how to solve my problem. The tables are like this:
Opportunities(business_developer_id FK) belongTo-> businessDevelopers(user_id FK) belongTo-> user
So I try to show all opportunities for a logged in business developer. But this doesn't seem to work:
public function qryOpportunities()
{
$opportunities = Opportunity::where('businessDeveloper.user_id', Auth::id())->with('businessDeveloper.user', 'consultantOpportunity.consultant.user', 'contactPerson', 'customer', 'headOfDepartment.user')->get();
return $opportunities;
}
A solution to show all opportunities from the logged-in business developer is much appreciated. Thanks in advance.
Try ->whereHas() :
public function qryOpportunities()
{
$opportunities = Opportunity::whereHas('businessDeveloper', function($q) {
$q->where('user_id', Auth::id());
})
->with('businessDeveloper.user', 'consultantOpportunity.consultant.user', 'contactPerson', 'customer', 'headOfDepartment.user')
->get();
return $opportunities;
}
You can check the docs of whereHas() here: https://laravel.com/docs/7.x/eloquent-relationships#querying-relationship-existence
I suggest you use this code:
public function qryOpportunities()
{
return Opportunity::query()
->whereHas('businessDeveloper', function($query) {
$query->where('user_id', Auth::id());
})->with('businessDeveloper.user', 'consultantOpportunity.consultant.user', 'contactPerson', 'customer', 'headOfDepartment.user')
->get();
}

How to Query if Multiple Columns Reference to the Same Table

I am facing an issue here. I have a table called application and it will record who requests the application, who approves it, and who rejects it. The issue is the Requestor_id, Approver_id and Rejector_id are references to the same table. How can I query for the requestor_name, approver_name, and rejector_name in Laravel
Application table
Requestor_id ( reference to user id)
Application_Status
Module_id
Approver_id ( reference to user id)
Rejector_id ( reference to user id)
created_at
updated_at
Below is what I have tried but it can only retrieve for the requestor name
$Approval_Logs = DB::table('application')
->select('application.id','application.Application_Status', 'users.name','application.Approver_id','application.Rejector_id', 'ems_application.Request_Category','application.updated_at')
->join('ems_application', 'ems_application.Application_id', '=', 'application.id')
->join('users', 'users.id', '=', 'application.requestor_id')
->whereIn('application.Application_Status',['approved','rejected'])
->get()
->toArray();
I hope I can receive some hints from you. Thanks in advance!
You may use aliases in your joins also.
$Approval_Logs = DB::table('application')
->select(
'application.id',
'application.Application_Status',
'application.Approver_id',
'approver.name as approver_name',
'application.requestor_id',
'requestor.name as requestor_name',
'application.Rejector_id',
'rejector.name as rejector_name',
'ems_application.Request_Category',
'application.updated_at'
)
->join('ems_application', 'ems_application.Application_id', '=', 'application.id')
->join('users as requestor', 'requestor.id', '=', 'application.requestor_id')
->join('users as approver', 'approver.id', '=', 'application.approver_id')
->join('users as rejector', 'rejector.id', '=', 'application.rejector_id')
->whereIn('application.Application_Status',['approved','rejected'])
->get()
->toArray();
I am not completely familiar with your application, however you may want to utilize left_join instead of join for the approver and rejector joins in the event that there was not an approver or rejector.
If you would like to do it the "Laravel" way. I would create a model called Application and create relations
class Application extends Model {
public function requestor(){
return $this->belongsTo(Users::class, 'requestor_id');
}
public function approver(){
return $this->belongsTo(Users::class, 'approver_id');
}
public function rejector(){
return $this->belongsTo(Users::class, 'rejector_id');
}
}
Then in your controller, you can run the following query:
$application = Application::whereHas('requestor', function($query) {
$query->where('first_name', 'John');
})->whereHas('approver', function($query) {
$query->where('first_name', 'Peter');
})->whereHas('rejector', function($query) {
$query->where('first_name', 'Michael');
})->get();
That should query the users table for the first names. I don't know how efficient this will be, but give it a try;

using sum with relation Laravel Eloquent ORM

i have Model Material which has
protected $with = ['costPrices'];
public function costPrices(){
return $this->hasMany(CostPrice::class);
}
the table of cost_prices has multiple quantity
//create_cost_prices_table
Schema::create('cost_prices', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('material_id');
$table->unsignedBigInteger('supplier_id');
$table->integer('quantity');
$table->timestamps();
});
i want to get (insufficient materials ) in another way select all materials form materials table where sum of all quantities of cost_prices table < 3 and get me the resulted materials not the count
You have 2 options:
You could fix your option with whereHas() by adding select and groupBy:
$materials = Material
::whereHas('costPrices', function($q) {
$q
->select('meterial_id')
->groupBy('material_id')
->havingRaw('SUM(quantity) > 4');
})
->get();
Or use subquery:
For laravel 6.x:
$materials = Material
::addSelect([
'cost_prices_sum' => CostPrice::selectRaw('sum(quantity)')->whereColumn('material_id', 'material.id')
])
->having('cost_prices_sum', '>', 4)
->get();
For laravel 5.x:
$materials = Material
::selectRaw('carts.*, (select sum(quantity) from cost_prices where cost_prices.matrerial_id = meterials.id) as cost_prices_sum')
->having('cost_prices_sum', '>', 4)
->get();
UPDATE: option with whereHas() is faster on a large number of rows.

Laravel eloquent where with relationship

I am stuck on transforming this SQL query to an eloquent query in Laravel. The SQL query works (tested in Sequel) but I cannot write it in eloquent ...
SELECT faqs.question FROM faqs
JOIN categories c ON c.id = faqs.category_id
WHERE c.subsite = 'sport'
This is what I have tried so far, but it returns all the questions, (ignoring the subsite filter).
$cat = Faq::with(['category' => function($query) use ($subsite) {
$query->where('subsite', $subsite);
}])->get();
Thanks for the help
Try this
$cat = Faq::query();
if (isset($subsite) && !empty($subsite) {
$query->whereHas('category', function ($query) use ($subsite) {
$query->where('subsite', $subsite);
});
}
$query->with('category')->get();
as per you core sql query, here is your laravel query.
$data = DB::table('faqs')
->join('categories', 'categories.id', '=', 'faqs.category_id')
->select('faqs.question')
->where('categories.subsite', '=', 'sport')
->get();
Hope this will help you!

SQL query to Laravel

I am trying to convert the following query to Laravel:
select libéllé
from application
where libéllé not in (select application_id from application_user
where user_id = $id)
Laravel whereNotIn supports closures for subqueries, so it will be as simple as this:
Using Eloquent:
// Add this to top of your file.
use App\{ Application, ApplicationUser };
// Get your entries.
$rows = Application::whereNotIn('libéllè', function($query) use ($id) {
$query->select('application_id')->from((new ApplicationUser)->getTable())->where('user_id', $id);
})->get(['libéllè']);
Using Query Builder:
$rows = DB::table('application')->whereNotIn('libéllè', function($query) use ($id) {
$query->select('application_id')->from('application_user')->where('user_id', $id);
})->get(['libéllè']);
Please Try it.
$results = DB::select(
select libéllé
from application
where (libéllé)
not in(
select application_id from application_user
where user_id = $id
)
);
Also see this answer: How to convert mysql to laravel query builder
Also see this documentation: https://laracasts.com/discuss/channels/laravel/laravel5-resolve-username-from-2-tables?page=1