简体   繁体   English

在 Doctrine Symfony2 中使用查询生成器实现 SQL 联合查询

[英]Implement SQL Union Query using Query Builder in Doctrine Symfony2

I'm currently using Symfony2 framework.我目前正在使用 Symfony2 框架。 I don't know how to join 2 of my query by Query Builder in Symfony2, I just can join them using SQL UNION query.我不知道如何通过 Symfony2 中的查询生成器加入我的 2 个查询,我只能使用 SQL UNION 查询加入它们。 Below is the query that returns correct results.下面是返回正确结果的查询。

SELECT * FROM (SELECT m.id, m.subject, m.date 
FROM message m JOIN message_incoming mi ON m.id = mi.id
WHERE m.recipient_id = 1
AND mi.trash = 1
AND mi.deleted = 0) AS y
UNION 
SELECT * FROM (SELECT m.id, m.subject, m.date 
FROM message m JOIN message_outgoing mo ON m.id = mo.id
WHERE m.originator_id = 1
AND mo.trash = 1
AND mo.sent = 1
AND mo.deleted = 0) AS z
ORDER BY date DESC

I was trying to join this code in just 1 query (without UNION) to get the correct result but I failed.我试图在 1 个查询(没有 UNION)中加入这段代码以获得正确的结果,但我失败了。

So how can I implement this query using query builder?那么我如何使用查询构建器实现这个查询呢?

Please advise, thanks.请指教,谢谢。

The best way to write such query without making to much hack on Doctrine2 itself would be to use NativeQuery .在不对 Doctrine2 本身进行太多修改的情况下编写此类查询的最佳方法是使用NativeQuery

The native/sql QueryBuilder uses the exactly same API as the ORM. native/sql QueryBuilder使用与 ORM 完全相同的 API。 And you are able to map result to an existing entity.并且您能够将结果映射到现有实体。

I don't know how stupid I am when joining 2 queries without checking the conditions.我不知道在不检查条件的情况下加入 2 个查询时我有多愚蠢。 This is the correct query:这是正确的查询:

SELECT m.id, m.subject, m.date
FROM message m 
JOIN message_incoming mi ON m.id = mi.id
JOIN message_outgoing mo ON m.id = mo.id
WHERE m.recipient_id = 1
AND mi .trash = 1
AND mi .deleted = 0
OR m.originator_id = 1
AND mo .trash = 1
AND mo .deleted =0
AND mo .sent = 1
ORDER by date DESC

I tried implement it through query builder:我尝试通过查询生成器实现它:

$queryBuilder = $this->entityManager->getRepository('EzxWebmailBundle:Message')
            ->createQueryBuilder('m')
            ->select('m.id','m.subject','m.date')
            ->join('m.message_outgoing','mo','ON','m.id = mo.id')
            ->join('m.message_incoming','mi','ON','m.id = mi.id')
            ->where('m.recipient_id = '.$userId)
            ->andWhere('mi.trash = 1')
            ->andWhere('mi.deleted = 0')
            ->orWhere('m.originator_id = '.$userId)
            ->andWhere('mo.trash = 1')
            ->andWhere('mo.deleted = 0')
            ->andWhere('mo.sent = 1')
            ->orderBy('m.date','DESC');
$result = $queryBuilder->getQuery()->getResult();

How surprisingly it returns incorrect result: So i tried to see what query was generated using :它返回不正确的结果是多么令人惊讶:所以我试图查看使用生成的查询:

var_dump($queryBuilder->getQuery());

And I really don't know why doctrine generates extra parenthesis as I get this result (carefully have a look at WHERE clause):我真的不知道为什么 doctrine 在我得到这个结果时会产生额外的括号(仔细看看 WHERE 子句):

SELECT m.id, m.subject, m.date FROM message m 
INNER JOIN message_outgoing mo ON m.id = mo.id
INNER JOIN message_incoming mi ON m.id = mi.id
WHERE ((m.recipient_id = 1 AND mi.trash = 1 AND mi.deleted = 0) OR m.originator_id = 1) AND mo.trash = 1 AND mo.deleted = 0 AND mo.sent = 1 
ORDER BY m.date DESC

So this must be the correct one if I add my own parenthsis:所以如果我添加自己的括号,这一定是正确的:

$queryBuilder = $this->entityManager->getRepository('EzxWebmailBundle:Message')
            ->createQueryBuilder('m')
            ->select('m.id','m.subject','m.date')
            ->join('m.message_outgoing','mo','ON','m.id = mo.id')
            ->join('m.message_incoming','mi','ON','m.id = mi.id')
            ->where('(m.recipient_id = '.$userId)
            ->andWhere('mi.trash = 1')
            ->andWhere('mi.deleted = 0)')
            ->orWhere('(m.originator_id = '.$userId)
            ->andWhere('mo.trash = 1')
            ->andWhere('mo.deleted = 0')
            ->andWhere('mo.sent = 1)')
            ->orderBy('m.date','DESC')

Feel a little stupid.觉得有点傻。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM