I have two tables 1) Prices and 2) Users
Owner is a column in the Prices table.
Both tables have a many to many relationship between price.users and users.price.
The query below returns all Prices shared by owner1 and user1.
Question: How do I fix this query where it only returns all owner1 prices that are not synced with user1.
If I use ->andWhere('u.id = :user1Id') then I get only records for user1.
If I use ->andWhere('u.id != :user1Id') then I get all owner record including user1 records.
Again I want all owner records except those that are synced with user1. I've tried the following so far:
1) $queryUsersPrices
->innerJoin('p.owner', 'o')
->leftJoin('p.users', 'u')
->andWhere('o.id = :ownerId')
/*I need to Remove records for u.id from results*/
->andWhere('u.id = :user1Id')
->setParameter('owner1Id', $owner->getId())
->setParameter('user1Id', $user->getId());
$userPrices = $queryUsersPrices->getQuery()->getResult();
2) $userPrices = $repository->createQueryBuilder($alias);
$userPrices
->select("u.prices")
->from("Price","p")
->innerJoin('p.users', 'u')
->andWhere('u.id = :userId')
->getDQL();
$query = $repository->createQueryBuilder($alias);
$query
->innerJoin($alias . '.owner', 'o')
->innerJoin($alias . '.priceType', 'pt')
->innerJoin($alias . '.model', 'm')
->where(
$query->expr()->not(
$query->expr()->in(
'p.id',
$userPrices
)
)
)
->andWhere('m.status = :m_status')
->andWhere('o.id = :adminId')
->andWhere('pt.site <> 1')
->setParameter('m_status', Model::STATUS_ACTIVE);
$result = $query->getQuery()->getResult();
3) $query = $repository->createQueryBuilder($alias);
$query
->innerJoin($alias . '.owner', 'o')
->innerJoin($alias . '.users', 'u', 'WITH', 'u.id =
:userId')
->innerJoin($alias . '.priceType', 'pt')
->innerJoin($alias . '.model', 'm')
->where('m.status = :m_status')
->andWhere('o.id = :adminId')
->andWhere('u.id IS NULL')
->andWhere('pt.site <> 1')
->setParameter('adminId', $adminUser->getId())
->setParameter('userId', $user->getId())
->setParameter('m_status', Model::STATUS_ACTIVE);
$test = $query->getQuery()->getResult();
Method #1 results in user1 prices only
Method #2 results in this error: Error: Method Doctrine\Common\Collections\ArrayCollection::__toString() must not throw an exception, caught Symfony\Component\Debug\Exception\ContextErrorException: Catchable Fatal Error: Object of class Doctrine\ORM\EntityManager could not be converted to string
Methos #3 results in owner prices only
THIS IS WHAT ACTUALLY WORKED BASED ON M Khalid Junaid ANSWER
$userPrices = $repository->createQueryBuilder('pr')
->innerJoin('pr.users', 'u')
->andWhere('u.id = :userId')
->setParameter('userId', $user->getId())
->getDQL();
$query = $repository->createQueryBuilder($alias);
$query
->innerJoin($alias . '.owner', 'o')
->innerJoin($alias . '.priceType', 'pt')
->innerJoin($alias . '.model', 'm')
->where(
$query->expr()->not(
$query->expr()->in(
$alias . '.id',
$userPrices
)
)
)
->andWhere('m.status = :m_status')
->andWhere('o.id = :adminId')
->andWhere('pt.site <> 1')
->setParameter('m_status', Model::STATUS_ACTIVE)
->setParameter('adminId', $adminUser->getId())
->setParameter('userId', $user->getId());
$result = $query->getQuery()->getResult();
I would suggest to break down your logic as
First select prices that belongs to $user->getId()
as
$userPrices = $this->createQueryBuilder("u")
->select("u.prices")
->from("YourBundleName:Prices","p")
->innerJoin('p.users', 'u')
->andWhere('u.id = :user1Id')
->getDQL();
Then get prices for owner which is $owner->getId()
and exclude prices from the subquery for $user->getId()
as
$qb = $this->createQueryBuilder("pr");
$qb->select("pr")
->from("YourBundleName:Price", "pr")
->innerJoin('pr.owner', 'o')
->where(
$qb->expr()->not(
$qb->expr()->in(
"pr.id",
$userPrices
)
)
)
->andWhere('o.id = :ownerId')
->setParameter('owner1Id', $owner->getId())
->setParameter('user1Id', $user->getId())
;
$query = $qb->getQuery();
$result = $query->getResult();
This would be more like to your original query but not the exact one I guess and might need some tweaks as per your mappings, but will give you an idea to move forward with this