应用复杂的doctrine子查询时,服务器崩溃

时间:2014-06-11 23:06:32

标签: symfony doctrine-orm

我正在尝试(不成功)这样做:

SELECT AVG (DISTINCT(DATEDIFF(E1.updated_date, E2.updated_date))) FROM 

(SELECT DISTINCT e1_.updated_date, e2_.id as id FROM engineering_details e1_ INNER JOIN engineerings e2_ ON e1_.engineering_id = e2_.id INNER JOIN projects p4_ ON e2_.project_id = p4_.id INNER JOIN `lines` l5_ ON e2_.line_id = l5_.id INNER JOIN statuses s6_ ON e1_.to_status_id = s6_.id WHERE e2_.Rev_asignee = 'Test User 1 [Eduardo Monto]' AND p4_.id = 8 AND l5_.id = 1 AND e2_.out_of_plan = 0 AND e1_.updated_date >= '2014-01-01' AND e1_.updated_date <= '2014-06-11' AND s6_.id = 16) as E1,

(SELECT DISTINCT e1_.updated_date, e2_.id as id FROM engineering_details e1_ INNER JOIN engineerings e2_ ON e1_.engineering_id = e2_.id INNER JOIN projects p4_ ON e2_.project_id = p4_.id INNER JOIN `lines` l5_ ON e2_.line_id = l5_.id INNER JOIN statuses s6_ ON e1_.to_status_id = s6_.id WHERE e2_.Rev_asignee = 'Test User 1 [Eduardo Monto]' AND p4_.id = 8 AND l5_.id = 1 AND e2_.out_of_plan = 0 AND e1_.updated_date >= '2014-01-01' AND e1_.updated_date <= '2014-06-11' AND s6_.id = 38) AS E2

WHERE E1.id = E2.id
DQL中的

到目前为止,我已经'翻译'到我认为它是SQL Above的DQL等价物。 我使用的是createQuery而不是createQueryBuilder,但我读到它是应用“子查询”的唯一方法,因此我最终改为createQueryBuilder。使用createQuery时出现错误“CLASS(找不到”

所以,我正在做

 $qb = $em->createQueryBuilder();
            $query = $qb->select('SELECT AVG(DISTINCT(DATEDIFF(E1.updatedDate, E2.updatedDate ))) AS AVGTREV')
                    ->from($qb->select('SELECT DISTINCT T1.updatedDate, eng.id as id HW\Bundle\EngMgmtBundle\Entity\EngineeringDetail T1 INNER JOIN T1.engineering eng INNER JOIN eng.project p INNER JOIN eng.line l INNER JOIN T1.toStatus ts WHERE eng.ReviewAsignee = :eng AND ts.id = 16
AND p.id = :project_id AND l.id = :line_id AND eng.outOfPlan = 0 AND T1.updatedDate >= :period_from AND T1.updatedDate <= :period_to'), 'E1')
                    ->from($qb->select('SELECT DISTINCT T2.updatedDate, eng.id as id HW\Bundle\EngMgmtBundle\Entity\EngineeringDetail T2 INNER JOIN T2.engineering eng INNER JOIN eng.project p INNER JOIN eng.line l INNER JOIN T2.toStatus ts WHERE eng.ReviewAsignee = :eng AND ts.id = 38
AND p.id = :project_id AND l.id = :line_id AND eng.outOfPlan = 0 AND T2.updatedDate >= :period_from AND T1.updatedDate <= :period_to'), 'E2')
                    ->setParameters(array('project_id' => $project, 'line_id' => $line, 'eng' => $user->getName(), 'period_from' => $period_from, 'period_to' => $period_to))
                    ->getQuery();
            $entities = $query->getResult();

我知道我不应该使用2'来自'但是我似乎找不到这样做的方法,因为主选择使用来自两个子查询的结果。

所以,当我尝试通过界面进行查询时,它不会抛出错误但是,它会“加载”然后更改为“网站不可用”...我很确定这是查询。 我究竟做错了什么?

3 个答案:

答案 0 :(得分:1)

Doctrine 2不支持使用createQueryBuilder进行复杂查询。您必须使用ResultSetMapping的本机查询。 createQueryBuilder转换导致问题的对象中的所有结果。要避免任何问题,请尝试本机查询。

请参阅以下链接以供参考。 http://doctrine-orm.readthedocs.org/en/latest/reference/native-sql.html

答案 1 :(得分:1)

或者您也可以使用Doctrine的DBAL

$query = "SELECT " ; // your query

// dbal connection from your controller
$conn = $this->container->get( 'doctrine.dbal.default_connection' );

// dbal connection from your entity repository
$conn = $this->getEntityManager()->getConnection();

$results = $conn->fetchAssoc( $query );

答案 2 :(得分:0)

$sql = "SELECT AVG (DISTINCT(DATEDIFF(E1.updated_date, E2.updated_date))) AS AVGTREV FROM

(SELECT DISTINCT e1_.updated_date, e2_.id as id FROM engineering_details e1_ INNER JOIN engineerings e2_ ON e1_.engineering_id = e2_.id INNER JOIN projects p4_ ON e2_.project_id = p4_.id INNER JOIN `lines` l5_ ON e2_.line_id = l5_.id INNER JOIN statuses s6_ ON e1_.to_status_id = s6_.id WHERE e2_.Rev_asignee = :engineer AND p4_.id = :project AND l5_.id = :line AND e2_.out_of_plan = 0 AND e1_.updated_date >= :begin_date AND e1_.updated_date <= :end_date AND s6_.id = 16) as E1,

(SELECT DISTINCT e1_.updated_date, e2_.id as id FROM engineering_details e1_ INNER JOIN engineerings e2_ ON e1_.engineering_id = e2_.id INNER JOIN projects p4_ ON e2_.project_id = p4_.id INNER JOIN `lines` l5_ ON e2_.line_id = l5_.id INNER JOIN statuses s6_ ON e1_.to_status_id = s6_.id WHERE e2_.Rev_asignee = :engineer AND p4_.id = :project AND l5_.id = :line AND e2_.out_of_plan = 0 AND e1_.updated_date >= :begin_date AND e1_.updated_date <= :end_date AND s6_.id = 38) AS E2

WHERE E1.id = E2.id";
            $params = array('engineer' => $user->getName(), 'project' => $project, 'line' => $line, 'begin_date' => $period_from, 'end_date' => $period_to);
            $em = $this->getDoctrine()->getManager();
            $stmt = $em->getConnection()->prepare($sql);
            $stmt->execute($params);
            $entities = $stmt->fetchAll();

我不得不使用原生的$ sql,虽然我对此并不完全感到满意但是我找不到使用Doctrine的方法。感谢@Kapil的回答。