与学说 dql 连接的子查询 [英] subquery in join with doctrine dql

查看:24
本文介绍了与学说 dql 连接的子查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to use DQL to create a query which looks like this in 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 来生成查询和子查询.我认为他们自己做了正确的事情,但我不能在 join 语句中将它们结合起来.如果 DQL 可以做到这一点,现在有人吗?我不能使用本机 SQL,因为我想返回真实对象,但我不知道该查询针对哪个对象运行(我只知道具有 uuid 和 locale 属性的基类).

I tried to use QueryBuilder to generate the query and subquery. I think they do the right thing by them selves but I can't combine them in the join statement. Does anybody now if this is possible with DQL? I can't use native SQL because I want to return real objects and I don't know for which object this query is run (I only know the base class which have the uuid and locale property).

    $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');

推荐答案

您不能在 DQL 的 FROM 子句中放置子查询.

You cannot put a subquery in the FROM clause of your DQL.

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

I will assume that your PK is {uuid, locale}, as of discussion with you on IRC. Since you also have two different columns in your query, this can become ugly. What you can do is putting it into the WHERE clause:

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 的(非空)语言环境数组进行比较.这是为了避免在您想匹配其他语言环境时破坏查询缓存.

Please note that I used a comparison against a (non empty) array of locales that you bind to to the :selectedLocales. This is to avoid destroying the query cache if you want to match against additional locales.

如果这样做没有真正的优势,我也不建议使用查询构建器来构建它,因为如果您动态添加条件,它只会更容易破坏查询缓存(另外,它涉及 3 个查询构建器!)

I also wouldn't suggest building this with the query builder if there's no real advantage in doing so since it will just make it simpler to break the query cache if you add conditionals dynamically (also, it's 3 query builders involved!)

这篇关于与学说 dql 连接的子查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆