2016-12-15 155 views
0

我有两个MySQL表和相应的实体:如何创建一个Doctrine子查询?

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) 

我试过许多东西像托马斯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(); 
+0

你会得到什么错误? –

+0

HTTP 500错误: 糟糕!发生错误 服务器返回了“500内部服务器错误”。最糟糕的是我没有收到任何错误信息,所以我不知道发生了什么问题。 – ACs

+1

你应该检查你的日志以了解实际上错误 –

回答

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()部分

0

调查日志我想出了,而不是

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

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

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

但是,这仍然给我一个错误。经过一番experimentingI想通了,如果执行子查询,它给这样的格式:

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))