2012-12-19 21 views
23

Im próbuje odtworzyć to zapytanie:„gdzie nie w” zapytaniu z konstruktora zapytań doktryna

SELECT * FROM `request_lines` 
where request_id not in(
select requestLine_id from `asset_request_lines` where asset_id = 1 
) 

w doktrynie konstruktora zapytań siedzę na where REQUEST_ID nie w (wybierz

Obecnie posiadają:

$linked = $em->createQueryBuilder() 
     ->select('rl') 
     ->from('MineMyBundle:MineRequestLine', 'rl') 
     ->where() 
     ->getQuery() 
     ->getResult(); 

Odpowiedz

33

trzeba użyć wyrażeń kreator zapytań, a to oznacza, że ​​trzeba dostęp do obiektu kwerend również kod jest łatwiej napisać, jeśli generują subsele. lista ct wyprzedzeniem:

$qb = $em->createQueryBuilder(); 

$nots = $qb->select('arl') 
      ->from('$MineMyBundle:MineAssetRequestLine', 'arl') 
      ->where($qb->expr()->eq('arl.asset_id',1)) 
      ->getQuery() 
      ->getResult(); 

$linked = $qb->select('rl') 
      ->from('MineMyBundle:MineRequestLine', 'rl') 
      ->where($qb->expr()->notIn('rl.request_id', $nots)) 
      ->getQuery() 
      ->getResult(); 
+0

Czy to nie jest możliwe w jednej kwerendzie? – Wilt

+1

Tak, sprawdź moją odpowiedź poniżej ... – Wilt

+0

Tak, używaj podejścia Wilt'a. – Lighthart

21

Jest możliwe, aby to zrobić w jednym zapytaniu Doctrine:

$qb = $this->_em->createQueryBuilder(); 
$sub = $qb; 

$sub = $qb->select('arl') 
      ->from('$MineMyBundle:MineAssetRequestLine', 'arl') 
      ->where($qb->expr()->eq('arl.asset_id',1)); 

$linked = $qb->select('rl') 
      ->from('MineMyBundle:MineRequestLine', 'rl') 
      ->where($qb->expr()->notIn('rl.request_id', $sub->getDQL())) 
      ->getQuery() 
      ->getResult(); 

Sprawdź reference in this answer here

+2

Szczerze, wolę tę odpowiedź od mojej własnej – Lighthart

+1

@Lighthart Lol :) Możesz awansować, jeśli chcesz ... – Wilt

+0

Świetne rozwiązanie, dzięki! To samo podejście można zastosować tam, gdzie logicznie można oczekiwać, że '-> gdzie ($ qb-> expr() -> eq ('x1.some_id', $ sub-> getDql()))' działa, ale '- > eq (...) 'lub' -> neq (...) 'oczekuje literału. Wystarczy użyć '-> in (...)' lub '-> notIn (...)' i ograniczyć wyniki podkwerendy do pojedynczej wartości zwracanej. – iisisrael