7

所以我一直在绞尽脑汁。在 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,所以关系是子->父。这是我的教义查询:

我的实体:

/**
 * @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来实现结果。唯一的父实体及其关联的子实体(如果它们存在),但我需要使用学说来实现它。再次感谢!

4

6 回答 6

0

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

    SELECT parent.*, child.*
    FROM table child, table parent 
    WHERE parent.id = child.parent_id
    OR child.parent_id IS NULL;
于 2014-06-28T07:13:26.180 回答
0

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

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

$em->createQueryBuilder()
->select(array('child', 'parent'))
->from('Entity', 'parent')
->leftjoin('parent.child', 'child')
->orderBy('parent.id','asc')
->getQuery()
->execute();
于 2013-08-09T21:40:15.033 回答
0

试试这个:

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;
于 2013-12-17T20:38:04.117 回答
0

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

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

因此,如果您只需要作为左连接提供的右连接 sql,请执行以下操作:

SELECT 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 为 null ORDER BY parent.id ASC

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

于 2014-03-21T16:27:57.227 回答
0

这两个语句是等价的:

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 中。

于 2017-12-04T12:29:06.093 回答
0

您可以使用与 Right Join 具有相同结果的 Join 子句。

SELECT p.*, c.*
FROM child c,parent p 
WHERE p.parent_id = c.parent_id
OR c.parent_id IS NULL;
于 2020-05-06T07:07:37.110 回答