Reputation: 1
I am facing an issue reguarding a doctrine request. I am using the queryBuilder but cannot find out how to do my request properly.
My database schema is like this : I have a ManyToMany relationship between two entities : "Lot" and "Bail".
What I want to do is get data related to one "Lot" if ALL its "Bail" follow one of these two rules :
I want to get the Lot only if ALL its Bail follow one of the two rules, meaning if one Bail whose not deleted or too old/recent, I don't get the Lot.
I have looked for several topics on leftJoin with condition but cannot seem to make it work.
Here is what I have done so far :
$queryBuilder = $this->createQueryBuilder('lot');
$queryBuilder
->select(
'typo.id as typologyId',
'typo.label as typology',
'lot.floor',
'sum(lot.sdp) as surface',
'sum(1) as total'
)
->leftJoin('lot.typology', 'typo')
->leftJoin('lot.batiment', 'batiment')
->leftJoin('lot.baux', 'bail', 'WITH', ':date not between bail.datePriseEffet and bail.dateFin or bail.deleteDate is not null')
->leftJoin('batiment.building', 'building')
->andWhere('building.id = :buildingId')
->addOrderBy('typo.label')
->addOrderBy('lot.floor')
->groupBy('typologyId, typology, lot.floor')
->setParameters(array(":buildingId" =>$buildingId, ":date" =>$date));
This is not working, I get the "Lot" if at least one of its Bail is deleted or too old/recent, not ALL of them.
How can I fix it ?
Maybe I can use the $queryBuilder->expr()->exists() function, but I don't really understand how it works.
Upvotes: 0
Views: 28
Reputation: 2106
A (very) late answer!
Let say you have a Library entity related to Book entities: Book <=ManyToOne
=>Library. Let say now that a book have a property $available
.
If you want to fetch all the libraries which ALL books are availables, this query will NOT work:
LibraryRepository
//....
$qb = $this->createQueryBuilder('l')
-> leftJoin('l.books', 'b')
-> andWhere("b.available = 1");
This will return libraries containing at least an available book.
To get the expected result, you have to build two queries: The first query ($qb) will fetch the entities we do not want (libraries with at least one book not available.
$qb = $this->createQueryBuilder('lib') // We're selecting libraries but using a different alias because 'l' is already used in the other query
->join('lib.books', 'bo')
->andWhere("bo.available = 0");
The second query $qb2 will select all libraries that do not belong to the first query results (hence the libraries wich all books are availables.
$qb2 = $this->createQueryBuilder('l');
$qb2 ->andWhere($qb->expr()->notIn('l.id', $qb->getDQL()));
Note that there's a trick with parameters: if you have to use a parameter in your fisrt query, you have to define it (setParameter()
method) inside the second query.
Upvotes: 0