【问题标题】:Convert MySQL with Subqueries to DQL 1.2将带有子查询的 MySQL 转换为 DQL 1.2
【发布时间】:2012-08-07 23:24:04
【问题描述】:

您好,我有来自 previous question 的以下查询,需要将其转换为 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;

我正在尝试找出如何在不求助于多个查询的情况下以另一种方式做到这一点。

谢谢。

【问题讨论】:

  • 是否允许使用视图而不是子查询?
  • 我从未使用过一种观点,但学说似乎支持它们。
  • 我已经阅读了关于学说中的观点,但它不会为我解决这个问题。我将不得不尝试将其重写为 DQL 查询,但我不知道是否可以这样做它。
  • 那么,您能否例如创建一个视图 CREATE VIEW max_activity_date AS SELECT contact_id, MAX(date) AS max_date FROM activity GROUP BY contact_id 并加入其中?
  • 我设法重写了它。视图不起作用,但能够以不同的方式进行。谢谢。

标签: mysql subquery dql


【解决方案1】:

使用原则,您不应该使用原始 sql 将子查询嵌套到 where 条件中。在更复杂的场景中你会遇到麻烦。而是使用createSubquery 来明确告知子查询的教义,让教义将其编译为 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/

【讨论】:

    【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 2015-04-02
      • 1970-01-01
      • 2014-10-11
      • 1970-01-01
      • 2014-05-06
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多