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

时间:2012-06-21 09:06:15

标签: php sql symfony doctrine query-builder

我目前正在使用Symfony2框架。我不知道如何通过Symfony2中的查询生成器加入我的查询,我只能使用SQL UNION查询加入它们。以下是返回正确结果的查询。

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

我试图在1个查询(没有UNION)中加入此代码以获得正确的结果,但我失败了。

那么如何使用查询构建器实现此查询?

请指教,谢谢。

2 个答案:

答案 0 :(得分:2)

编写此类查询而不对Doctrine2本身进行大量破解的最佳方法是使用NativeQuery

native / sql QueryBuilder使用与ORM完全相同的API。并且您可以将结果映射到现有实体。

答案 1 :(得分:0)

我不知道在没有检查条件的情况下加入2个查询时我是多么愚蠢。 这是正确的查询:

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

我尝试通过查询构建器实现它:

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

令人惊讶的是它返回错误的结果!所以我尝试使用以下方法查看生成的查询:

var_dump($queryBuilder->getQuery());

我真的不知道为什么教义会产生额外的括号,因为我得到了这个结果(仔细看看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

如果我添加自己的父母,那么这一定是正确的:

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

感觉有点愚蠢。