将本机SQL转换为Doctrine 2 DQL - 自我引用多对多

时间:2014-05-17 11:47:47

标签: mysql sql symfony doctrine-orm doctrine

我试图根据这个原生sql查询生成doctrine 2 DQL查询:

SELECT f2.follower_id, u.*
            FROM 
                users u,
                user_followers f1
                join user_followers f2 ON (f2.user_id = f1.follower_id AND f2.follower_id != f1.user_id )
            WHERE f1.user_id = :user_id
            AND u.id = f2.follower_id
            AND f2.follower_id NOT IN (
                SELECT follower_id 
                FROM user_followers 
                WHERE user_id = :user_id
            )
            GROUP BY 1
            HAVING count(*) > 1

它基于用户实体,它可以自我引用多对多的关系:

/**
 * @ORM\ManyToMany(targetEntity="App\UserBundle\Entity\User", mappedBy="following")
 */
private $followers;

/**
 * @ORM\ManyToMany(targetEntity="App\UserBundle\Entity\User", inversedBy="followers", cascade={"persist", "remove"})
 * @ORM\JoinTable(name="user_followers",
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="follower_id", referencedColumnName="id")}
 *      )
 */
private $following;

我完全难过,对如何实施它没有任何想法。 任何帮助都将非常感激。

1 个答案:

答案 0 :(得分:0)

您需要将查询分为两部分。一个是让跟随者id在内部查询中检查NOT IN。

首先关注追随者身份,

下一个查询将是这样的,

$fid = $qb1->select('u.follower_id')
           ->from('UserFollowers','u')
           ->where('u.user_id = :ui')
           ->setParameter('ui', $user_id)

然后在下一个查询中,您需要在验证NOT IN的位置传递它。 dql就是这样的。

$dql = $qb2->select('f2.follower_id','u')
          ->from('Users','u')
          ->leftJoin('u.following', 'f2', Expr\Join::ON, 'f2.user_id = u.id')
          ->where('u.id = f2.follower_id')
          ->andWhere('f2.follower_id NOT IN :folid')
          ->setParameter('folid', $fid)
          ->groupBy(1)
          ->andHaving($qb2->expr()->count('u'), 0);

您可以从此处获取更多信息: - http://docs.doctrine-project.org/en/latest/reference/query-builder.html