2012-08-12 55 views
20

我想選擇不是特定服務的成員。我有3個表:doctrine2中的子查詢NOTIN函數

  • membre
  • service
  • membre_servicemembreservice之間的關係)

我使用學說2和SQL我的查詢是:

SELECT m.* FROM membre m WHERE m.`id` NOT IN (
    SELECT ms.membre_id FROM membre_service ms WHERE ms.service_id != 29 
) 

在學說中,我d ○:

$qb = $this->_em->createQueryBuilder(); 
$qb2 = $qb; 
$qb2->select('m.id') 
     ->from('Custom\Entity\MembreService', 'ms') 
     ->leftJoin('ms.membre', 'm') 
     ->where('ms.id != ?1') 
     ->setParameter(1, $service); 

    $qb = $this->_em->createQueryBuilder(); 
    $qb->select('m') 
     ->from('Custom\Entity\Membre', 'm') 
     ->where($qb->expr()->notIn('m.id', $qb2->getDQL()) 
    ); 
    $query = $qb->getQuery(); 
    //$query->useResultCache(true, 1200, __FUNCTION__); 

    return $query->getResult(); 

我得到了以下錯誤:

Semantical Error] line 0, col 123 near 'm WHERE ms.id': Error: 'm' is already defined.

回答

35

相同的別名不能在同一個查詢

$qb = $this->_em->createQueryBuilder(); 
$qb2 = $qb; 
$qb2->select('m.id') 
    ->from('Custom\Entity\MembreService', 'ms') 
    ->leftJoin('ms.membre', 'm') 
    ->where('ms.id != ?1'); 

$qb = $this->_em->createQueryBuilder(); 
$qb->select('mm') 
    ->from('Custom\Entity\Membre', 'mm') 
    ->where($qb->expr()->notIn('mm.id', $qb2->getDQL()) 
); 
$qb->setParameter(1, $service); 
$query = $qb->getQuery(); 

return $query->getResult(); 

理想情況下,你應該使用許多一對多定義的2倍關係爲你的實體,在這種情況下,你的查詢將會簡單得多。

+0

感謝您的回答! MembreService已經在多對多...... 你真的幫我一把!並看到我的編輯的最終答案。 願上帝保佑你... – 2012-08-12 23:03:56

+0

如果你在子查詢中使用參數:$ qb-> setParameters($ qb2-> getParameters());儘管您可能想要$ qb-> setParameters(array_merge($ qb2-> getParameters(),$ qb-> getParameters()))以避免重寫來自外部查詢的參數。 – Omn 2016-03-04 01:32:19

+0

嗯...拿我最後的評論用一粒鹽,只顯示工作在一些版本的教條...在其他版本setParameters替換,而不是增加參數... – Omn 2016-03-04 02:27:04

11

其實,如果你使用的是Symfony2的庫類,你也可以做到以下幾點:

$in = $this->getEntityManager()->getRepository('Custom:MembreService') 
    ->createQueryBuilder('ms') 
    ->select('identity(ms.m)') 
    ->where(ms.id != ?1); 

$q = $this->createQueryBuilder('m') 
    ->where($q->expr()->notIn('m.id', $in->getDQL())) 
    ->setParameter(1, $service); 

return $q->getQuery()->execute(); 
+0

謝謝你。我正在尋找一種方法來處理不同的存儲庫,你的解決方案就是這麼做的。 – mason81 2014-09-23 19:58:16

+0

在'$ q-> expr()'中,'$ q'是什麼? – psylosss 2016-08-10 14:28:16

+1

$ q是QueryBuilder的一個實例。正確的代碼如下所示: ''q $ = $ this-> createQueryBuilder('m'); $ Q->其中($ Q-> EXPR() - > notIn()......))''' – versedi 2017-03-25 14:30:06

4

您可以使用(NOT) MEMBER OF

<?php 
$query = $em->createQuery('SELECT m.id FROM Custom\Entity\Membre WHERE :service NOT MEMBER OF m.services'); 
$query->setParameter('service', $service); 
$ids = $query->getResult(); 

更多的例子見documentation