join using eloquent to not take common column from joined table - laravel

I'm joining two tables that both have tag_id (i.e. album.tag_id and photo.tag_id)
function GetJoined()
{
return Album::join('photos', 'photos.tag_id', '=', 'albums.tag_id')
}
but I don't want that resulting query to keep reminding me that this was a join from two tables
GetJoined()->where('tag_id', 1);
will be all like
'tag_id' in where clause is ambiguous
Any suggestions?

Related

Laravel belongsToMany withPivot() and distinct()

How do I group the results of a belongsToMany() relationship that has withPivot() values?
groupBy() produces an SQL error and distinct() does work if there is no withPivot() data.
But I need the pivot data in the results.
// Relationship: room to chores
public function chores(){
return $this->belongsToMany(
Chore::class,
'maps'
)
->withPivot('id', 'room_id', 'chore_id', 'person_id')
->groupBy('chores.id');
}
SQL ERROR
SELECT list is not in GROUP BY clause and contains nonaggregated column 'pivot.maps.room_id' which is not functionally dependent on columns in GROUP BY clause
You could use a SELECT clause to specify which columns should be included in the results. This allows you to specify which columns should be included in the results, while still grouping the results by the chores.id column.
public function chores()
{
return $this->belongsToMany(Chore::class, 'maps')
->select('chores.*', 'pivot.id', 'pivot.room_id', 'pivot.chore_id', 'pivot.person_id')
->withPivot('id', 'room_id', 'chore_id', 'person_id')
->groupBy('chores.id');
}

Laravel. Join three tables from three way pivot where one column (jsonb) contains an array of id's

I have a table called user_business_survey which has a user_uuid, business_uuid and a third containing one or more survey_uuid's IN A JSONB column. I need to query the DB to bring back the following two scenarios: USER1 belongs to BUSINESS1 AND HAS SURVEY A, SURVEY B, SURVEY C then also USER1 belongs to BUSINESS3 AND HAS SURVEY B, SURVEY D, SURVEY E
This is the query I am trying but to no avail. It return empty.
DB::table('user_business_survey')
->select(['*'])
->leftJoin('businesses', 'businesses.uuid', '=', 'user_business_survey.business_uuid')
->leftJoin('surveys', 'surveys.uuid', '=', 'user_business_survey.survey_uuid')
->whereJsonContains('survey_uuid', 'surveys.uuid')
->where('user_business_survey.user_uuid', '=', $id)
->get();
DB table is as follows:
user_uuid
business_uuid
surveys_uuids is an column with one or more survey id's as jsonb
I need to itrate through all id's and join them from the jsonb column
I thank you in advance for any help to build this query

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.

Laravel where clause of current and related table

how to compare current table column to related table column
example: A.quantity < B.criticalQuantity
similarly like this AModel::where('quantity', "<", "b.criticalQuantity")->get()
the relations is
B HasMany A
A BelongsTo B
you can use whereColumn
it is specialist in comparing columns not a column with value.
anyway you can't directly compare two columns from two table, you have to join them first by anyway of join types
something like:
$values = ModelA::join('model_b_table_name', 'model_b_table_name.id', 'model_a_table_name.model_b_id')
->whereColumn('model_b_table_name.column.quantity', 'model_b_table_name.quantity')
->get();
you must be specific in joining the table, you should join by the columns that consist the relation between the two tables.
->whereRaw('table_1.name = table_2.name')

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

Resources