0

I am trying to create a query builder with doctrine with an query expression like the following:

WHERE a < ((VALUE FROM SUBQUERY 1) / (VALUE FROM SUBQUERY 2))

I've been able to accomplish a < (VALUE FROM SUBUQERY 1) but as soon I add the second sub query, doctrine throws an error of "Expected Literal, got 'SELECT'"

My database model is a Company entity related with a Sales Entity and a Quotations entity. I want to filter companies which the ratio quotation/sale is greater or lower of some value.

This is company entity:

#[ORM\Entity(repositoryClass: CompanyRepository::class)]
class Company 
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id;

    #[ORM\OneToMany(mappedBy: 'company', targetEntity: Quotation::class, cascade: ['all'], orphanRemoval: true, fetch: 'EXTRA_LAZY')]
    private Collection $quotations;

    #[ORM\OneToMany(mappedBy: 'company', targetEntity: Sale::class, cascade: ['all'], orphanRemoval: true, fetch: 'EXTRA_LAZY')]
    private Collection $sales;
}

This is the query builder I am building:

$qb = $companyRepository->createQueryBuilder('item');

$qbInQuotation = $this->getEntityManager()->createQueryBuilder()
    ->from(Quotation::class, 'ratioQuotationMin')
    ->where('ratioQuotationMin.company = item')
    ->select('COUNT(ratioQuotationMin.id)');

$qbInSale = $this->getEntityManager()->createQueryBuilder()
    ->from(Sale::class, 'ratioSaleMin')
    ->where('ratioSaleMin.company = item')
    ->select('COUNT(ratioSaleMin.id)');

$qb->andWhere(
    $qb->expr()->lte(
        ':ratioMin',
        '(('.$qbInSale->getDQL().') / ('.$qbInQuotation->getDQL().'))'
    ))
    ->setParameter('ratioMin', $data->getQuotationsMax());

The resulting DQL is the following:

SELECT item 
FROM App\Entity\Company\Company item 
WHERE :ratioMin <= ((SELECT COUNT(ratioSaleMin.id) FROM App\Entity\Sales\Sale ratioSaleMin WHERE ratioSaleMin.company = item) / (SELECT COUNT(ratioQuotationMin.id) FROM App\Entity\Sales\Quotation ratioQuotationMin WHERE ratioQuotationMin.company = item)) 
ORDER BY item.name ASC

As an sql query, this is a correct query, but I think doctrine does not like the double parenthesis ((. But removing the double parenthesis it throws an error "Expected end of string, got '/'"

David Rojo
  • 2,337
  • 1
  • 22
  • 44

0 Answers0