与doctrine dql连接的子查询

时间:2012-10-31 16:59:18

标签: doctrine-orm subquery inner-join dql

我想使用DQL在SQL中创建一个如下所示的查询:

select
    e.*
from
    e
inner join (
    select
        uuid, max(locale) as locale
    from
        e
    where
        locale = 'nl_NL' or
        locale = 'nl'
    group by
        uuid
) as e_ on e.uuid = e_.uuid and e.locale = e_.locale

我尝试使用QueryBuilder生成查询和子查询。我认为他们自己做正确的事情,但我不能在连接声明中将它们结合起来。如果DQL有可能,现在有人吗?我不能使用本机SQL,因为我想返回真实对象,我不知道这个查询运行的对象(我只知道具有uuid和locale属性的基类)。

    $subQueryBuilder = $this->_em->createQueryBuilder();
    $subQueryBuilder
        ->addSelect('e.uuid, max(e.locale) as locale')
        ->from($this->_entityName, 'e')
        ->where($subQueryBuilder->expr()->in('e.locale', $localeCriteria))
        ->groupBy('e.uuid');

    $queryBuilder = $this->_em->createQueryBuilder();
    $queryBuilder
        ->addSelect('e')
        ->from($this->_entityName, 'e')
        ->join('('.$subQueryBuilder.') as', 'e_')
        ->where('e.uuid = e_.uuid')
        ->andWhere('e.locale = e_.locale');

1 个答案:

答案 0 :(得分:0)

您不能将子查询放在DQL的FROM子句中。

我将假设您的PK为{uuid, locale},与您在IRC上的讨论一样。由于查询中还有两个不同的列,因此可能会变得很难看。 您可以做的是将其放入WHERE子句:

select
    e
from
    MyEntity e
WHERE
    e.uuid IN (
        select
            e2.uuid
        from
            MyEntity e2
        where
            e2.locale IN (:selectedLocales)
        group by
            e2.uuid
    )
    AND e.locale IN (
        select
            max(e3.locale) as locale
        from
            MyEntity e3
        where
            e3.locale IN (:selectedLocales)
        group by
            e3.uuid
    )

请注意,我使用了与:selectedLocales绑定的(非空)语言环境数组进行比较。这是为了避免在要与其他语言环境匹配时销毁查询缓存。

我也不建议使用查询构建器构建它,如果这样做没有真正的优势,因为如果你动态添加条件,它会简化破解查询缓存(同样,它涉及3个查询构建器!)