How to use countDistinct in Doctrine query builder (Symfony)

matt_jay picture matt_jay · Aug 5, 2014 · Viewed 13.4k times · Source

I am trying to count the distinct number of IDs returned for a query with his:

$query = $repo->createQueryBuilder('prov')
        ->select('c.id')
        ->innerJoin('prov.products', 'prod')
        ->innerJoin('prod.customerItems', 'ci')
        ->innerJoin('ci.customer', 'c')
        ->where('prov.id = :brand')
        ->setParameter('brand', $brand)
        ->countDistinct('c.id')
        ->getQuery();

I am getting this error though:

Attempted to call method "countDistinct" on class "Doctrine\ORM\QueryBuilder" [...]

I have also tried

$query = $repo->createQueryBuilder('prov')
        ->select('c.id')
        ->innerJoin('prov.products', 'prod')
        ->innerJoin('prod.customerItems', 'ci')
        ->innerJoin('ci.customer', 'c')
        ->where('prov.id = :brand')
        ->setParameter('brand', $brand)
        ->expr()->countDistinct('c.id')
        ->getQuery();

which leads to this error:

Error: Call to a member function getQuery() on a non-object in

I can't get any other pointers as to how to do this differently from the documentation

Answer

Kamil Adryjanek picture Kamil Adryjanek · Aug 5, 2014

countDistinct is method of Expr class and COUNT DISTINCT need to be in SELECT statement so:

$qb = $repo->createQueryBuilder('prov');
$query = $qb
        ->select($qb->expr()->countDistinct('c.id'))
        ->innerJoin('prov.products', 'prod')
        ->innerJoin('prod.customerItems', 'ci')
        ->innerJoin('ci.customer', 'c')
        ->where('prov.id = :brand')
        ->setParameter('brand', $brand)
        ->getQuery();

should work. Or simply:

$query = $repo->createQueryBuilder('prov')
        ->select('COUNT(DISTINCT c.id)')
        ->innerJoin('prov.products', 'prod')
        ->innerJoin('prod.customerItems', 'ci')
        ->innerJoin('ci.customer', 'c')
        ->where('prov.id = :brand')
        ->setParameter('brand', $brand)
        ->getQuery();