2012-08-07 96 views
2

您好我有從previous question以下查詢,需要將其轉換爲DQL爲原則1.2。但事實證明,DQL不支持連接中的子查詢。與子查詢轉換MySQL來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 2012-08-07 23:27:25

+0

我從來沒有使用過一個視圖,但教義似乎支持他們。 – Ben 2012-08-08 02:47:48

+0

我看了一下意見學說,它不會解決這個問題,我..我將不得不嘗試和重寫這是一個DQL查詢,但我不知道是否有可能做到這一點。 – Ben 2012-08-08 07:21:24

回答

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明確地告訴教義有關子查詢,讓學說把它編譯成DQL,然後窩到你那裏的條件。因此,您的查詢應該是這個樣子:

$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/