Laravel Eloquent join if column null - laravel

I have two tables users/invoices in 1:n relation. When someone creats an invoice it saves the user_id. Also it's possible (optional) to set a manager (column: project_management_user_id). If there is no manager set (NULL), I want to get the user, who created the record. So for now I have this query. It gives me all invoices with the manager (but not that ones with manager = null.
$query = Invoice::join('users', 'invoices.project_management_user_id', '=', 'users.id')
->select('users.name as name', 'users.color as color', DB::raw("count(invoices.id) as count"))
->get();
Is it possible to add some if-clause like "if project_management_user_id is null, take the user_id"? I read about the whereNull() function, but it filters my whole query

Use leftJoin instead of join in the query.

Related

how to fetch data from 3 different table in laravel using advance join

I have 3 table
This is my first table cart_items .👇🏻
This is my second table ecomm_products.👇🏻
This is my Third table ecomm_sellers.👇🏻
$result = DB::table('cart_items')
->join('ecomm_products','ecomm_sellers',function($join){
$join->on('ecomm_products.id','=','cart_items.product_id')->where('cart_items.order_id','=',1);
$join->on('ecomm_products.seller_id','=','ecomm_sellers.id');
})
->where('cart_items.user_id','=',Auth::user()->id)
->select('ecomm_products.product_name','ecomm_products.showcase_image','ecomm_products.selling_price','cart_items.quantity','cart_items.id')
->get();
But I am getting an error ⛔⛔⛔
strtolower(): Argument #1 ($string) must be of type string, Closure given
When I have not included 3 tables (ecomm_sellers) till the query is running good but when I add it sends me some errors.
The question is: Why I am getting this error and why this query is not working, What else I can add so that my query working fine.
You cannot join two tables in by passing the table names as arguments to join. If you check the API documentation of the join method you can see that its signature is:
$this join(string $table, Closure|string $first, string|null $operator = null, string|null $second = null, string $type = 'inner', bool $where = false)
so you can only join two tables at a time and if you want to join more than two tables you chain another call to the join method.
try this:
$result = DB::table('cart_items')
->join('ecomm_products', 'ecomm_products.id', '=', 'cart_items.product_id')
->join('ecomm_sellers' , 'ecomm_products.seller_id', '=', 'ecomm_sellers.id')
->where('cart_items.order_id', '=', 1)
->where('cart_items.user_id', '=', Auth::user()->id)
->select([
'ecomm_products.product_name',
'ecomm_products.showcase_image',
'ecomm_products.selling_price',
'cart_items.quantity',
'cart_items.id'
])
->get();
You can find examples for Laravel query builder joins here

How do I Join table with multiple id in same column?

How do I apply join for this kind of table where document_id is stored in array. I am aware about explode function but I really dont know how to use. I do not want to use for loop but I am expecting better idea to join this table. If I have to add something then I will add.
$row = DB::table('service_documents')->select('service_documents.document_id', 'service_documents.service_id')->get();
$idArr = explode(',', $row);
dd($idArr);
$documents = DB::table('service_documents')->select('service.name_np as serviceName',
'documents.name_np as documentName', 'service_documents.*')
->join('service', 'service_documents.service_id', '=', 'service.id')
->join('documents', 'service_documents.document_id', '=', 'documents.id')
->get();
This is my join query in laravel
The best solution (to have a performant query) is to add a new pivot table document_service_document with service_document_id and document_id as fields.
Then populate that table using existing document_id field and adapt all the codes linked to that field to use the pivot table instead.
for that, and after, you can use manyToMany relation or simple join and get the results you need the easy way.

How to query multiple where in laravel

I have a query that gets all the message between two id (user_id and to_user_id). I want to select all the query all the message of user in the two tables.
I have already made two where and it doesn't seem to work. It is just returning null.
$last_message = DB::table('messages')
->select('content')
->where('user_id','=',Auth::user()->id)
->where('to_user_id','=',Auth::user()->id)
->orderBy('updated_at', 'desc')
->first();
I expect the output of all the message of user
You should check on this Auth::user()->id,
to see if it has a value or not. Also check on the datatype between table field and data source in query builder.

Eloquent methods lumen

I have belongsToMany relationship between items and vehicle.
items can be assigned to multiple vehicles. same vehicle can b assigned to multiple items. so my pivot table item_vehicle have extra column date which will show that when vehicle is assigned to item.
here is my query.
select `items`.`id`, `items`.`name`, `items`.`area` as `total_area`,
`item_vehicle`.`date`, `vehicles`.`name` as `vehicle_name`,
SUM(parcel_vehicle.area) as processed_area
from `parcels`
inner join `item_vehicle` on `item_vehicle`.`p_id` = `items`.`id`
inner join `vehicles` on `item_vehicle`.`t_id` = `vehicles`.`id`
where `item_vehicle`.`date` < '?' and `items`.`processed` = ? and `vehicles`.`name`=?
group by items.id
what will be the eloquent way of doing this
Item::with(['vehicle'=>function($q){$q->wherePivot('date','<','2019/2/12');}])->whereHas('vehicle',function($q){$q->where('vehicles.id','2');})->where('processed',1)->where('id',4)
->get();
my concerns is it should run only one query
$parcels = Parcel::join('item_vehicle', 'item_vehicle.pid', '=' ,'items.id')
->join('vehicles', 'vehicles.id', '=' ,'item_vehicle.t_id')
->where('item_vehicle.date', '<', $date)
->where('items.processed', $processed)
->where('vehicles.name', $vehicleName)
->select(
'items.id',
'items.name',
\DB::raw('items.area as total_area'),
'item_vehicle.date',
\DB::raw('vehicles.name as vehicle_name'),
\DB::raw('SUM(parcel_vehicle.area) as processed_area')
)
->groupBy('items.id')
->get();
However, you have non-aggregated columns in select and you are doing group by. To make this work you might need to disable mysql's only_full_group_by mode

Getting Count of Rows With Join in Laravel

What is the correct way to get a count of rows whose specified column is a foreign key of another table. Here's what I mean:
I have 2 tables providers and products. The providers table has primary key provider_idand the table products has a foreign key reference to provider_id via a column named the same, provider_id. My intention is to fetch the details of each provider including all their products, that is a total of all instances where provider_id in the products table matched providers_id in the providers table.
Here's my code:
$data = DB::table('providers')
->join('products', 'products.provider_id', '=', 'providers.provider_id')
->select(
'providers.provider_id AS id',
'providers.provider_name AS name',
DB::raw("count(products->where('products.provider_id','=','providers.provider_id')) AS total_products"),
'providers.claims AS claims',
'providers.settlements AS settlements')
->groupBy('provider')
->get();
This seems not to work as I am getting the error below:
Undefined property: Illuminate\Database\MySqlConnection::$id (View: /var/www/test/app/resources/views/agent/serviceproviders/index.blade.php)
What am I doing wrong?
The issue was in how I was counting the rows and how I was grouping the data for proper counting. I feel so dumb, this was too easy. Below is the correct code:
$data = DB::table('providers')
->join('products', 'products.provider_id', '=', 'providers.provider_id')
->select(
'providers.provider_id AS id',
'providers.provider_name AS name',
DB::raw("count(products.provider_id) AS total_products"))
->groupBy('providers.provider_id')
->get();

Resources