所以我现在已经绞尽脑汁待了一会儿。在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子句应该用什么来过滤它们。
所以我的问题是“教义是否有办法正确加入”或“我如何使用左连接操作,如右连接”?
--- --- EDIT
你们所说的关于改变我选择的表的排序是正确的,但是我使用的是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
我想用正确的连接sql实现结果。具有关联子级的唯一父实体(如果存在)但我需要使用doctrine来实现它。再次感谢!
答案 0 :(得分:0)
@ 491243的评论是正确的:如果您使用的是sql,这将是一个微不足道的问题,因为左右连接很容易转换,关系谓词可以按任何顺序表示。
真正的问题似乎不是如何将右连接重写为左连接,而是如何在另一个方向上遍历您的关系。大概你不能做这样的事情吗?:
$em->createQueryBuilder()
->select(array('child', 'parent'))
->from('Entity', 'parent')
->leftjoin('parent.child', 'child')
->orderBy('parent.id','asc')
->getQuery()
->execute();
答案 1 :(得分: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;
答案 2 :(得分: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子句不仅过滤了孩子,也过滤掉了孩子。这对返回的子数据有影响:如果孩子是个孩子,孩子将不会被退回。
答案 3 :(得分:0)
不熟悉Doctrine脚本,但是......在大多数SQL脚本中,这种旧式JOIN
应该与RIGHT JOIN
获得相同的结果:
SELECT parent.*, child.*
FROM table child, table parent
WHERE parent.id = child.parent_id
OR child.parent_id IS NULL;
答案 4 :(得分: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中以保证完整性。
答案 5 :(得分:0)
您可以使用Join子句,其结果与Right Join相同。
SELECT p.*, c.*
FROM child c,parent p
WHERE p.parent_id = c.parent_id
OR c.parent_id IS NULL;