与学说 dql 连接的子查询
Posted
技术标签:
【中文标题】与学说 dql 连接的子查询【英文标题】:subquery in join with doctrine dql 【发布时间】:2012-10-21 05:06:49 【问题描述】:我想使用 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 来生成查询和子查询。我认为他们自己做了正确的事情,但我不能在 join 语句中将它们结合起来。如果 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');
【问题讨论】:
对子查询执行 INNER JOIN 就是 what I'm trying to do。你找到解决办法了吗? 【参考方案1】:您不能在 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 个查询构建器!)
【讨论】:
我认为这不会起作用,因为结果中每一行的 uuid 和语言环境之间没有关系。 是的,你是对的......这不会真正起作用。可以concat
uuid
和locale
字段然后进行检查,但是在这种情况下任何键都将无用(甚至不是一个好的解决方案)以上是关于与学说 dql 连接的子查询的主要内容,如果未能解决你的问题,请参考以下文章
Symfony 学说 DQL 随机结果在使用 MaxResult 的查询中
如何删除学说 Doctrine Raw Sql 查询中的特定 dql 部分?
第七周 Java语法总结之数据库大全_DDL_DML_DQL_约束_备份与还原_表的关系_三大范式_多表查询(内连接_外连接_子查询)_musql事务_隔离级别