【问题标题】:How to use left join like right join in Doctrine如何在 Doctrine 中像右连接一样使用左连接
【发布时间】:2012-09-14 00:50:45
【问题描述】:

所以我已经绞尽脑汁有一段时间了。在 Doctrine 中没有右连接的概念。我知道您可以像使用右连接一样使用左连接,但我无法在我的示例中弄清楚这就是我在这里的原因。

我的例子: 我在 Doctrine 中有一个实体,它与自身具有一对一的关系,称为“父级”。 我试图让所有实体及其子项(如果它们存在)没有重复。

有了正确的加入,这很简单,因为我可以说:

    SELECT parent.*, child.*
    FROM table child
    RIGHT JOIN table parent ON parent.id = child.parent_id
    WHERE parent.parent_id is null;

但是使用左连接,我返回的结果我无法弄清楚应该使用什么 where 子句来过滤掉它们。

所以我的问题是“学说是否有办法进行右连接”或“我怎样才能像右连接一样使用左连接操作”?

---编辑---

你们所说的关于更改我从中选择的表格的顺序是正确的,但我使用的是 Doctrine,所以关系是 child->parent。这是我的教义查询:

我的实体:

/**
 * @Entity
 * @Table(name="entity")
 */
class Entity
{
...
/**
 * @OneToOne(
 *     targetEntity="Entity",
 *     fetch="EAGER"
 * )
 * @JoinColumn(name="parent_id", referencedColumnName="id")
 */
private $parent;
...
}

我的学说选择声明:

$em->createQueryBuilder()
->select(array('child', 'parent'))
->from('Entity', 'child')
->leftjoin('child.parent', 'parent')
->orderBy('parent.id','asc')
->getQuery()
->execute();

我不确定如何以及是否可以切换表格的顺序。我还尝试创建从实体到自身的另一种关系(就像我做父母的方式一样),但称它为孩子。但是当我用新的模式学说更新数据库时抛出了错误。

有什么想法吗?感谢您的快速回复!

---编辑 2---

左连接sql和结果:

SELECT child.id, child.changed_timestamp, child.parent_entity_id, parent.id,
  parent.changed_timestamp, parent.parent_entity_id 
FROM content child 
LEFT JOIN content parent ON child.parent_entity_id = parent.id   
ORDER BY parent.id ASC

child_id    child_timestamp parent_entity_id    parent_id   parent_timestamp    parent_entity_id
1           8/16/12 20:29   NULL                NULL        NULL                NULL
7           9/20/12 16:07   NULL                NULL        NULL                NULL
8           8/17/12 16:08   NULL                NULL        NULL                NULL
9           8/17/12 20:44   NULL                NULL        NULL                NULL
10          8/17/12 21:03   NULL                NULL        NULL                NULL
11          8/17/12 21:17   NULL                NULL        NULL                NULL
194         9/19/12 9:58    NULL                NULL        NULL                NULL
195         9/20/12 10:38   NULL                NULL        NULL                NULL
196         9/19/12 11:58   NULL                NULL        NULL                NULL
197         NULL            196                 196         9/19/12 11:58       NULL
200         9/20/12 16:02   1                   1           8/16/12 20:29       NULL
202         9/20/12 16:35   NULL                NULL        NULL                NULL
204         9/21/12 8:41    NULL                NULL        NULL                NULL
206         NULL            204                 204         9/21/12 8:41        NULL

右连接结果:

SELECT child.id, child.changed_timestamp, child.parent_entity_id, parent.id, 
 parent.changed_timestamp, parent.parent_entity_id 
FROM content child 
RIGHT JOIN content parent ON child.parent_entity_id = parent.id   
WHERE parent.parent_entity_id is null
ORDER BY parent.id ASC

child_id    child_timestamp parent_entity_id    parent_id   parent_timestamp    parent_entity_id
200         9/20/12 16:02   1                   1           8/16/12 20:29       NULL
NULL        NULL            NULL                7           9/20/12 16:07       NULL
NULL        NULL            NULL                8           8/17/12 16:08       NULL
NULL        NULL            NULL                9           8/17/12 20:44       NULL
NULL        NULL            NULL                10          8/17/12 21:03       NULL
NULL        NULL            NULL                11          8/17/12 21:17       NULL
NULL        NULL            NULL                194         9/19/12 9:58        NULL
NULL        NULL            NULL                195         9/20/12 10:38       NULL
197         NULL            196                 196         9/19/12 11:58       NULL
NULL        NULL            NULL                202         9/20/12 16:35       NULL
206         NULL            204                 204         9/21/12 8:41        NULL

我想用正确的join sql来实现结果。唯一的父实体及其关联的子实体(如果它们存在),但我需要使用学说来实现它。再次感谢!

【问题讨论】:

  • child RIGHT JOIN tableparent ON parent.id = child.parent_idtableparent LEFT JOIN child ON parent.id = child.parent_id 相同
  • 请提供示例数据和所需的输出。
  • 嗨@Alex Mamut,您知道如何正确连接吗?我在这里遇到了同样的问题。

标签: sql doctrine left-join


【解决方案1】:

@491243 的评论是正确的:如果您使用的是 sql,这将是一个小问题,因为左连接和右连接很容易转换,并且关系谓词可以以任何顺序表示。

真正的问题似乎不是如何将右连接重写为左连接,而是如何在另一个方向上遍历您的关系。想必你不能只做这样的事情吗?:

$em->createQueryBuilder()
->select(array('child', 'parent'))
->from('Entity', 'parent')
->leftjoin('parent.child', 'child')
->orderBy('parent.id','asc')
->getQuery()
->execute();

【讨论】:

    【解决方案2】:

    试试这个:

    SELECT
        parenttable.*, childtable.*
    FROM childtable
    RIGHT JOIN parenttable ON parenttable.id = childtable.parent_id
    WHERE
        parenttable.parent_id IS NULL
        AND
        childtable.childid IS NOT NULL;
    

    【讨论】:

      【解决方案3】:

      您发布的左连接没有:WHERE parent.parent_entity_id 为空

      我猜测在您的数据中,这意味着该记录本身不是一个孩子。

      因此,如果您只需要作为左连接提供的右连接 sql,则可以:

      选择 child.id、child.changed_timestamp、child.parent_entity_id、parent.id、 parent.changed_timestamp,parent.parent_entity_id FROM content parent LEFT JOIN content child ON child.parent_entity_id = parent.id
      WHERE parent.parent_entity_id 为空 ORDER BY parent.id ASC

      注意:如果您的数据允许多代,例如grand-children 等,上面的 where 子句不仅过滤掉了孩子,还过滤掉了孙子。这对返回的子数据有影响:如果是孙子,则不会返回子数据。

      【讨论】:

        【解决方案4】:

        对 Doctrine 脚本不是很熟悉,但是……这种老式的JOIN 应该与大多数 SQL 脚本中的RIGHT JOIN 实现相同的结果:

            SELECT parent.*, child.*
            FROM table child, table parent 
            WHERE parent.id = child.parent_id
            OR child.parent_id IS NULL;
        

        【讨论】:

          【解决方案5】:

          这两个语句是等价的:

          SELECT parent.*, child.*
          FROM table child
          RIGHT JOIN table parent ON parent.id = child.parent_id
          WHERE parent.parent_id is null;
          
          SELECT parent.*, child.*
          FROM table parent 
          LEFT JOIN table child ON child.parent_id = parent.id 
          WHERE parent.parent_id is null;
          

          我从不使用 RIGHT JOIN。我认为它只是为了完整性而包含在 SQL 中。

          【讨论】:

            【解决方案6】:

            您可以使用与右联接具有相同结果的联接子句。

            SELECT p.*, c.*
            FROM child c,parent p 
            WHERE p.parent_id = c.parent_id
            OR c.parent_id IS NULL;
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-07-28
              • 1970-01-01
              • 1970-01-01
              • 2015-01-11
              相关资源
              最近更新 更多