Laravel where clause of current and related table - laravel

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')

Related

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

Laravel Eloquent select function cause empty relation

Following is my query
$user = User::select(['uuid','name','about'])->with(['education','work'])->first();
this returns empty data for relationship education and work,
but if I remove select function from query I am getting data in relationship and it also returns all columns of user table which I don't want.
how can solve this problem
The problem is that relationships (with(...)) execute an additional query to get the related results. Let's say you have one to many relationship where users have many works. User::with('work')->find(1) will then execute these 2 queries:
select user where id = 1 and select works where user_id = 1.
So basically in order to be able to execute the second query (fetch relationship data) you need to include id (or whichever column you're referencing) in you select statement.
Fix:
$user = User::select(['uuid','name','about', 'id'])->with(['education','work'])->first();
Same principle in different forms applies to all relationships. For example in the inverse of hasMany which is belongsTo you would need to select the foreign key (for example user_id).

join using eloquent to not take common column from joined table

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?

Count the number of rows in many to many relationships in Hibernate

I have three of many tables in Oracle (10g) database as listed below. I'm using Hibernate Tools 3.2.1.GA with Spring version 3.0.2.
Product - parent table
Colour - parent table
ProductColour - join table - references colourId and prodId of Colour and Product tables respectively
Where the ProductColour is a join table between Product and Colour. As the table names imply, there is a many-to-many relationship between Product and ProductColour. I think, the relationship in the database can easily be imagined and is clear with only this much information. Therefore, I'm not going to explore this relationship at length.
One entity (row) in Product is associated with any number entities in Colour and one entity (row) in Colour can also be associated with any number of entities in Product.
Let's say as for an example, I need to count the number of rows available in the Product table (regarding Hibernate), it can be done something like the following.
Object rowCount = session.createCriteria(Product.class)
.setProjection(Projections.rowCount()).uniqueResult();
What if I need to count the number of rows available in the ProductColour table? Since, it is a many-to-many relationship, it is mapped in the Product and the Colour entity classes (POJOs) with there respective java.util.Set and no direct POJO class for the ProductColour table is available. So the preceding row-counting statement doesn't seem to work in this scenario.
Is there a precise way to count the number of rows of such a join entity in Hibernate?
I think you should be able to do a JPQL or HQL along the lines.
SELECT count(p.colors) FROM Product AS p WHERE p.name = :name ... other search criteria etc
or
SELECT count(c.products) FROM Color AS c WHERE c.name = :name .... other search criteria
From Comment below, this should work:
Long colours=(Long) session.createQuery("select count(*) as cnt from Colour colour where colour.colourId in(select colours.colourId from Product product inner join product.colours colours where product.prodId=:prodId)").setParameter("prodId", prodId).uniqueResult();

Linq - Join Confusion

For the sake of this question, let's assume I have tables 'A' and 'B' and there is a 1:1 relationship between them. In a Linq query, I can do the following:
from row in A
where row.B.Description = someValue
select A
Where row.B is the reference to table 'B'.
However, let's now assume there is a 1:M relationship between 'A' and 'B'. The above query no longer works. It seems I need to explicitly use 'join' as follows:
from row in A
join row1 in B on row.BId = row1.BId
where row1.Description = someValue
select A
My question is this. Am I correct that for 1:M relationships, 'join' is required? Or is there are way to do this query, without using join, like in the 1:1 case?
You don't have to join explicitly, select many will do the trick
from row in A
from row1 in row.B
where row1.Description == someValue
select row
alternatively (although I really don't like it)
from row in A
where row.B.Any(b => b.Description == someValue)
select row
With the first option you will need to do a Distinct() on the result if there are many B's that have the same description.
In theory, you should always use Join, if nothing else, then for clarity and readability. But in any 1:M case, you need to specify how the tables relate to each other. Just as you would have to do in SQL.

Resources