非常感谢@AdrienCarniero提供的替代查询结构,该查询结构使用简单的JOIN对最高版本进行排序,其中实体的timeMod小于联接表timeMod。
替代查询
SELECt view_version.* FROM view_version#inner join to get the best versionLEFT JOIN view_version AS best_version ON best_version.viewId = view_version.viewId AND best_version.timeMod > view_version.timeMod#join other tables for filter, etcINNER JOIN view ON view.id = view_version.viewIdINNER JOIN content_type ON content_type.id = view.contentTypeIdWHERe view_version.siteId=1# LIMIT Best VersionAND best_version.timeMod IS NULLAND view.contentTypeId IN (2)ORDER BY view_version.title ASC;
使用教义QueryBuilder
$em = $this->getDoctrine()->getManager();$viewVersionRepo = $em->getRepository('GutensiteCmsBundle:ViewViewVersion');$queryBuilder = $viewVersionRepo->createQueryBuilder('vv') // Join Best Version ->leftJoin('GutensiteCmsBundle:ViewViewVersion', 'bestVersion', 'WITH', 'bestVersion.viewId = e.viewId AND bestVersion.timeMod > e.timeMod') // 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) // LIMIT Joined Best Version ->andWhere('bestVersion.timeMod IS NULL') ->andWhere('view.contentTypeId IN(:contentTypeId)')->setParameter('contentTypeId', $contentTypeIds) ->addOrderBy('e.title', 'ASC');$query = $queryBuilder->getQuery();$results = $query->getResult();在性能方面,它实际上取决于数据集。有关详细信息,请参见此讨论。
提示:该表应在这两个值(viewId和timeMod)上都包含索引,以加快结果的速度。 我不知道这是否也会从两个领域的单一索引中受益。
在某些情况下,使用原始JOIN方法的本机SQL查询 可能
会更好,但使用动态创建它的扩展代码范围编译该查询,并使映射正确将是一件痛苦的事情。因此,这至少是一种替代解决方案,希望对其他人有所帮助。



