如何制作一个Doctrine子查询?

时间:2016-12-15 09:15:24

标签: symfony doctrine-orm

我有两个mysql表和相应的实体:

Question
--------
id
text
level


Asked
--------
* @ORM\ManyToOne(targetEntity="QuestionEntity")
* @ORM\JoinColumn(name="question", referencedColumnName="id")
question 
user

我想查询具有特定级别的所有问题,并且未向特定用户询问该问题。如何使用实体管理器查询构建器执行此操作? 使用MySQL语法,查询将是:

SELECT 
  *
FROM 
  Question
WHERE 
  Question.level = 1
  AND Question.id NOT IN( SELECT Asked.question FROM Asked WHERE Asked.user = 23)

我尝试了多个像Tomasz Madeyski评论的内容,但我仍然遇到500内部服务器错误。这是我的代码:(我测试了子查询,当它独立时很好)

$em = $this->getDoctrine()->getManager();
    $fbUser = $em->getRepository(FbUserEntity::class)->findOneBy(['fbId' => $session->get('fb_user_id')]);

$qb = $em->createQueryBuilder();
$qb2 = $qb;

$questions = $qb->select('q')
    ->from('MyBundle:QuestionEntity', 'q')
    ->where('q.level = :level')
    ->setParameter('level', $level)
    ->andWhere($qb->expr()->notIn(
        'q.id',
        $qb2->select('a.question')
            ->from('LMyBundle:AskedEntity', 'a')
            ->where('a.user = :userid')
            ->setParameter('userid', $fbUser->getId())
            ->getDQL()
    ))
    ->getQuery()
    ->getResult();

2 个答案:

答案 0 :(得分:0)

尝试这样的事情:

$qb = $em->createQueryBuilder();
$subQuery = $qb->select('a.question')
    ->from('YourBundle:Asked', 'a')
    ->andWhere('a.user = 23')


$query = $qb->select('q')
    ->from('YourBundle:Question', 'q')
    ->andWhere('q.level = 1')
    ->andWhere($qb->expr()->notIn('q.id', $subQuery->getDQL())
    ->getQuery()
    ->getResult()

此处的关键是$qb->expr()->notIn()部分

答案 1 :(得分:0)

调查日志我发现不是

$qb = $em->createQueryBuilder();
$qb2 = $qb;

我应该为qb2创建一个新的queryBuilder:

$qb = $em->createQueryBuilder();
$qb2 = $em->createQueryBuilder();

但这仍然给我一个错误。经过一些实验,我发现如果子查询被执行,它会给出类似这样的格式:

array (size=2)
  0 => 
    array (size=1)
      'question' => int 1
  1 => 
    array (size=1)
      'question' => int 2

所以我像这样运行子查询结果:

$alreadyAsked = [];
foreach($asked as $q){
    $alreadyAsked[] = $q['question'];
}

将$ alreadyAsked数组传递给主查询,然后就可以了:

->andWhere($qb->expr()->notIn('q.id', $alreadyAsked))