2012-08-07 4 views
2

안녕하세요 저는 previous question에서 다음 쿼리를 받아서 Doctrine 1.2 용 DQL로 변환해야합니다. 그러나 DQL은 조인에서 서브 쿼리를 지원하지 않습니다.Subqueries를 사용하여 DQL 1.2로 변환하십시오.

SELECT * FROM contact c 
    LEFT JOIN 
    (SELECT a1.contact_id, a1.date, a1.activity_type_id FROM activity a1 
     JOIN (SELECT contact_id, MAX(DATE) DATE FROM activity GROUP BY contact_id) a2 
     ON a1.contact_id = a2.contact_id AND a1.date = a2.date 
    ) a 
    ON c.id = a.contact_id 

WHERE a.activity_type_id = 2; 

여러 쿼리를 사용하지 않고이 방법을 수행하는 방법을 알아 내려고하고 있습니다.

감사합니다.

+0

당신이 하위 쿼리 대신보기를 사용할 수 있습니까 그래서 쿼리는 다음과 같이 보일 것이다? – Neil

+0

나는보기를 사용한 적이 없지만 교리가 그들을지지하는 것처럼 보입니다. – Ben

+0

나는 doctrine에 대한 의견을 읽었으며 나를 위해 해결하지 않을 것이다. 나는이 것을 DQL 쿼리로 다시 작성해야만 할 것이지만, 가능한지 모르겠다. – Ben

답변

2

최종 쿼리

SELECT * FROM contact c 
    LEFT JOIN activity ON c.id = contact_id 
    WHERE ROW (c.id,DATE) IN (SELECT contact_id, MAX(date) date FROM activity GROUP BY contact_id) 
    AND activity_type_id = 2 

최종 DQL :

$q->from('Contact c') 
->leftJoin('c.Activity a')  
->where('ROW (c.id, date) IN (SELECT a1.contact_id, MAX(a1.date) a1.date FROM Activity a1 GROUP BY a1.contact_id)') 
->andWhere('a.activity_type_id = ?', $filterActivityTypeId); 
3

교리를 사용하면해야하지 조건 원시 SQL을 사용하는 경우에 둥지 서브 쿼리. 보다 복잡한 시나리오에서 문제가 발생할 것입니다. 대신 createSubquery을 사용하여 하위 쿼리에 대해 doctrine에 명시 적으로 알려 주면 doctrine이이를 DQL로 컴파일 한 다음 where 조건에 중첩시킵니다. 또 다른 예는 여기에서 찾을 수 있습니다

$q->from('Contact c') 
    ->leftJoin('c.Activity a') 
; 

$subquery = $q->createSubquery() 
    ->select("a1.contact_id, MAX(a1.date) a1.date") 
    ->from("Activity a1") 
    ->groupby("a1.contact_id") 
; 

$q->where('ROW (c.id, date) IN ('.$subquery->getDql().')') 
    ->andWhere('a.activity_type_id = ?', $filterActivityTypeId) 
; 

:

https://www.philipphoffmann.de/2012/08/29/a-bulletproof-pattern-for-creating-doctrine-subqueries-of-any-complexity/