NOT IN 在多对多关系中使用 Doctrine QueryBuilder 进行查询
NOT IN query with Doctrine QueryBuilder in a Many to Many relation
在我的 Symfony2 项目中,我有两个实体 "contact" 和 "settings",具有多对多关系:
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Settings", cascade={"persist"})
* @ORM\JoinColumn(nullable=true)
*/
private $settings;
实体设置有一个属性"parametre",这是一个简单的字符串。
现在我想获取所有没有任何设置的联系人 "parametre" 是 "THEMES"。
我可以在 SQL 中使用这样的查询来做到这一点:
SELECT DISTINCT(c.id) FROM contact c WHERE c.id
NOT IN (SELECT cs.contact_id FROM contact_settings cs
INNER JOIN Settings s ON s.id = cs.settings_id
WHERE s.parametre = "THEMES")
但我不知道如何使用 Doctrine 的查询生成器来完成。
到目前为止,这是我尝试过的方法:
$query = $this->createQueryBuilder('c')
->join('c.settings', 's');
$qb2 = $qb;
$qb2->select('s2')
->from('AppBundle\Entity\Settings', 's')
->where('s2.parametre = :parametre');
$query->where(($qb->expr()->notIn('s', $qb2->getDQL())));
$query->setParameter('parametre', 'THEMES');
$result = $query->getQuery()->getResult();
那return 没有任何结果。
谢谢!
您可以尝试这样的操作:
$subQueryBuilder = $this->getEntityManager()->createQueryBuilder();
$subQuery = $subQueryBuilder
->select(['cs.id'])
->from('AcmeDemoBundle:Contact', 'cs')
->innerJoin('cs.settings', 's')
->where('s.parameter = :parameter')
->setParameter('parameter', 'THEMES')
->getQuery()
->getArrayResult()
;
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$query = $queryBuilder
->select(['c'])
->from('AcmeDemoBundle:Contact', 'c')
->where($queryBuilder->expr()->notIn('c.id', ':subQuery'))
->setParameter('subQuery', $subQuery)
->getQuery()
;
$result = $query->getResult();
这只是您问题的一个示例。我无法提供完整的示例,因为我不知道您的实体的结构...
xurshid29 接受的答案将使用 2 个查询。但是通过在“->notIn()”函数中使用 getDQL(),您可以在 1 个查询中完成:
$subQueryBuilder = $this->getEntityManager()->createQueryBuilder();
$subQuery = $subQueryBuilder
->select('cs.id')
->from('AcmeDemoBundle:Contact', 'cs')
->innerJoin('cs.settings', 's')
->where('s.parameter = :parameter') // move setParameter() to main queryBuilder!
;
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$query = $queryBuilder
->select('c')
->from('AcmeDemoBundle:Contact', 'c')
->where($queryBuilder->expr()->notIn('c.id', $subQuery->getDQL()))
->setParameter('parameter', 'THEMES') // setParameter() from the subQuery must go here
->getQuery()
;
$result = $query->getResult();
警告!不要尝试将 DQL 设置为参数,这将导致字符串而不是真正的 SQL 语法。
所以这是错误的,不会起作用:
// THIS IS WRONG
->where($queryBuilder->expr()->notIn('c.id', ':subQuery'))
->setParameter('subQuery', $subQuery->getDQL())
在我的 Symfony2 项目中,我有两个实体 "contact" 和 "settings",具有多对多关系:
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Settings", cascade={"persist"})
* @ORM\JoinColumn(nullable=true)
*/
private $settings;
实体设置有一个属性"parametre",这是一个简单的字符串。
现在我想获取所有没有任何设置的联系人 "parametre" 是 "THEMES"。
我可以在 SQL 中使用这样的查询来做到这一点:
SELECT DISTINCT(c.id) FROM contact c WHERE c.id
NOT IN (SELECT cs.contact_id FROM contact_settings cs
INNER JOIN Settings s ON s.id = cs.settings_id
WHERE s.parametre = "THEMES")
但我不知道如何使用 Doctrine 的查询生成器来完成。 到目前为止,这是我尝试过的方法:
$query = $this->createQueryBuilder('c')
->join('c.settings', 's');
$qb2 = $qb;
$qb2->select('s2')
->from('AppBundle\Entity\Settings', 's')
->where('s2.parametre = :parametre');
$query->where(($qb->expr()->notIn('s', $qb2->getDQL())));
$query->setParameter('parametre', 'THEMES');
$result = $query->getQuery()->getResult();
那return 没有任何结果。
谢谢!
您可以尝试这样的操作:
$subQueryBuilder = $this->getEntityManager()->createQueryBuilder();
$subQuery = $subQueryBuilder
->select(['cs.id'])
->from('AcmeDemoBundle:Contact', 'cs')
->innerJoin('cs.settings', 's')
->where('s.parameter = :parameter')
->setParameter('parameter', 'THEMES')
->getQuery()
->getArrayResult()
;
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$query = $queryBuilder
->select(['c'])
->from('AcmeDemoBundle:Contact', 'c')
->where($queryBuilder->expr()->notIn('c.id', ':subQuery'))
->setParameter('subQuery', $subQuery)
->getQuery()
;
$result = $query->getResult();
这只是您问题的一个示例。我无法提供完整的示例,因为我不知道您的实体的结构...
xurshid29 接受的答案将使用 2 个查询。但是通过在“->notIn()”函数中使用 getDQL(),您可以在 1 个查询中完成:
$subQueryBuilder = $this->getEntityManager()->createQueryBuilder();
$subQuery = $subQueryBuilder
->select('cs.id')
->from('AcmeDemoBundle:Contact', 'cs')
->innerJoin('cs.settings', 's')
->where('s.parameter = :parameter') // move setParameter() to main queryBuilder!
;
$queryBuilder = $this->getEntityManager()->createQueryBuilder();
$query = $queryBuilder
->select('c')
->from('AcmeDemoBundle:Contact', 'c')
->where($queryBuilder->expr()->notIn('c.id', $subQuery->getDQL()))
->setParameter('parameter', 'THEMES') // setParameter() from the subQuery must go here
->getQuery()
;
$result = $query->getResult();
警告!不要尝试将 DQL 设置为参数,这将导致字符串而不是真正的 SQL 语法。 所以这是错误的,不会起作用:
// THIS IS WRONG
->where($queryBuilder->expr()->notIn('c.id', ':subQuery'))
->setParameter('subQuery', $subQuery->getDQL())