在多对多关系中的多个连接条件

Wad*_*les 6 php mysql symfony doctrine-orm

我正在编写一个包含三个类的应用程序,用户,帖子和组.

用户可以发帖,但可以代表他们自己和/或代表他们的一个组进行发布.两个或更多用户也可以在没有组的情况下相互结合发布帖子.我试图找到一种方法来计算用户与其关联的帖子数量,无论是通过他们自己还是他们的一个组,并且在两个关联仅存在于一个帖子的情况下,它应该只计为一个.

用户:

class User {
    /**
     * @ManyToMany(targetEntity="Post", inversedBy="users")
     */
    private $posts;

    /**
     * @ManyToMany(targetEntity="Group", inversedBy="users")
     */
    private $groups;
Run Code Online (Sandbox Code Playgroud)

和另外两个entites上的等效mappedBy.

我写了一个似乎可以解决这个问题的MySQL查询

SELECT COUNT(DISTINCT posts.id), users.name FROM users
LEFT JOIN post_user ON post_user.user_id = user.id
LEFT JOIN group_user ON group_user.user_id = user.id
LEFT JOIN post_group ON post_group.group_id = group_user.group_id
LEFT JOIN posts ON
    posts.id = post_user.post_id OR
    posts.id = post_group.post_id
GROUP BY users.id
Run Code Online (Sandbox Code Playgroud)

它给了我一个用户列表,以及他们关联的帖子数量.

我很难找到一种方法将这种查询写入ORM语言.问题来自于加入ManyToMany连接表的必要性,而不是实体的表本身.在过去,我已经能够使用'WITH'语句编写一个condtional join.

$qb = $this->createQueryBuilder('u')
    ->select('COUNT(DISTINCT p.id), u.name')
    ->leftJoin('u.groups', 'g')
    ->leftJoin('MyBundle:Post', 'p', 'WITH', 'p = u.posts OR p = g.posts')
Run Code Online (Sandbox Code Playgroud)

这个错误

Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
Run Code Online (Sandbox Code Playgroud)

很明显,问题源于'u.posts'和'g.posts'引用表而不是字段.

我不确定Doctrine是否能够进行这种查询,我希望这可以在数据库端完成,因为可能有一个大型数据集需要处理,这需要按计数排序从结果集.

有没有办法使用DQL引用连接表本身?如果没有,是否有一种不同类型的关系架构可以解决这个问题?

小智 0

在我看来,您主要关心的问题应该是数据库中存在多对多关系,而不是代码无法正常工作。

使用两个查询的并集创建一个视图。从一个查询中的组收集用户 ID,然后从另一查询中的独立用户收集用户 ID。一旦你看到了视图,你就可以进行计数了。