2

こんにちは、以前の質問から次のクエリがあり、Doctrine 1.2 の DQL に変換する必要があります。ただし、DQL は結合でのサブクエリをサポートしていないことが判明しました。

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;

複数のクエリに頼らずに、これを別の方法で行う方法を見つけようとしています。

ありがとう。

4

2 に答える 2

3

doctrine を使用すると、raw sql を使用してサブクエリを where 条件にネストしないでください。より複雑なシナリオでは問題が発生します。代わりに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.philippoffmann.de/2012/08/29/a-bulletproof-pattern-for-creating-doctrine-subqueries-of-any-complexity/

于 2012-09-01T06:57:01.333 に答える
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);
于 2012-08-10T13:34:24.810 に答える