Select count() in Doctrine DQL with left join manyToMany unidirectional relation where user does NOT have relation specific group

最后都变了- 提交于 2019-12-23 09:04:32

问题


Situaction: I am trying to select count() in DQL for users NOT in specific group.

Standard ManyToMany unidirectional relation between User and Group entities from FOSUserBundle (and SonataUserBundle). System: Symfony 2.5, Doctrine 2.4.

Entity User

P.S. this is not real code copied. It is not possible because there are several layers extending with different config files in different formats and places, so if you spot mistype, this is not the problem.

namespace RAZ\UserBundle\Entity;
/**
 * @ORM\Table(name="fos_user_user")
 */
class User
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var Collection
     *
     * @ORM\ManyToMany(targetEntity="Group")
     * @ORM\JoinTable(name="fos_user_user_group")
     */
    protected $groups;
}

Entity Group

namespace RAZ\UserBundle\Entity;
/**
 * @ORM\Table(name="fos_user_group")
 */
class Group
{
/**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
}

Question: can this even be done in DQL?

Question very similar to: How to get entities in a many-to-many relationship that do NOT have a corresponding linked entity with DQL and Doctrine? The difference is I need to check for only one specific group.

Working SQL (returns 1423):

SELECT COUNT(*) cnt
FROM fos_user_user u
LEFT JOIN fos_user_user_group dug ON u.id = dug.user_id AND dug.group_id = 70
WHERE dug.user_id IS NULL

Incorrectly working DQL (returns 3208):

SELECT COUNT(u)
FROM RAZUserBundle:User u
LEFT JOIN u.groups dug WITH dug.id = 70
WHERE dug IS NULL

Problem is DQL generates different SQL:

SELECT COUNT(u.id)
FROM fos_user_user u
LEFT JOIN fos_user_user_group ug ON u.id = ug.user_id
LEFT JOIN fos_user_group g ON g.id = ug.group_id AND (g.id = 70)
WHERE g.id IS NULL

Any suggestions?


回答1:


I don't think your DQL is quite right. Can you post it? But in the meantime, this should work.

   $em = $this->getDoctrine()->getManager();
   $qb = $em->createQueryBuilder();

   $result = $qb->select('COUNT(u)')
                ->from('UserBundle:User' , 'u')
                ->leftJoin('u.UserGroup','g')
                ->where('g.GroupId = :id')
                ->andWhere('g.UserId = :null')
                ->setParameter('id', 70)
                ->setParameter('null', null)
                ->getQuery()
                ->getOneOrNullResult();

Also writing your DQL this way is easier to read ;)




回答2:


The only way I managed to do it in DQL is use subquery:

SELECT COUNT(u)
FROM RAZUserBundle:User u
WHERE u.id NOT IN (
    SELECT u2.id
    FROM RAZUserBundle:User u2
    JOIN u2.groups g WITH g.id = 70
)


来源:https://stackoverflow.com/questions/25886829/select-count-in-doctrine-dql-with-left-join-manytomany-unidirectional-relation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!