Is it possible to use the Doctrine QueryBuilder in an INNER JOIN temporary table from a full SELECT that includes GROUP BY ?
The ultimate goal is to choose the best version of the recording. I have a viewVersion table that has several versions with the same viewId but with a different timeMod. I want to find a version with the latest timeMod (and do many other complex associations and filters on request).
People initially assume that you can do GROUP BY viewId and then ORDER BY timeMod , but ORDER BY does not affect GROUP BY, and MySQL will return random results. There is a ton of answers (like here ) that explain the problem using GROUP and offer a solution, but it's hard for me to interpret Doctrine docs to find a way to implement SQL with Doctrine QueryBuilder (if possible). Why am I just not using DQL? I may have to, but I have a lot of dynamic filters and associations that are much easier to do with QueryBuilder, so I wanted to see if this is possible.
MySQL sample to play in Doctrine QueryBuilder
SELECT vv.* FROM view_version vv
Theoretical solution using Query Builder (not working)
I think JOIN should introduce a DQL statement, for example.
$em = $this->getDoctrine()->getManager(); $viewVersionRepo = $em->getRepository('GutensiteCmsBundle:View\ViewVersion'); $queryMax = $viewVersionRepo->createQueryBuilder() ->addSelect('MAX(timeMod) AS timeModMax') ->addSelect('viewId') ->groupBy('viewId'); $queryBuilder = $viewVersionRepo->createQueryBuilder('vv') // I tried putting the query in a parenthesis, to no avail ->join('('.$queryMax->getDQL().')', 'version', 'WITH', 'vv.viewId = version.viewId AND vv.timeMod = version.timeModMax') // Join other Entities ->join('e.view', 'view') ->addSelect('view') ->join('view.contentType', 'contentType') ->addSelect('contentType') // Perform random filters ->andWhere('vv.siteId = :siteId')->setParameter('siteId', 1) ->andWhere('view.contentTypeId IN(:contentTypeId)')->setParameter('contentTypeId', $contentTypeIds) ->addOrderBy('e.title', 'ASC'); $query = $queryBuilder->getQuery(); $results = $query->getResult();
My code (which may not match the example above):
SELECT e, view, contentType FROM Gutensite\CmsBundle\Entity\View\ViewVersion e INNER JOIN ( SELECT MAX(v.timeMod) AS timeModMax, v.viewId FROM Gutensite\CmsBundle\Entity\View\ViewVersion v GROUP BY v.viewId ) version WITH vv.viewId = version.viewId AND vv.timeMod = version.timeModMax INNER JOIN e.view view INNER JOIN view.contentType contentType WHERE e.siteId = :siteId AND view.contentTypeId IN (:contentTypeId) ORDER BY e.title ASC
This answer seems to indicate that it is possible in other contexts such as IN , but when I try to use the above method in JOIN, I get an error:
[Semantical Error] line 0, col 90 near '(SELECT MAX(v.timeMod)': Error: Class '(' is not defined.