2017-02-23 10 views
0

카탈로그에서 제품 및 기사가 있습니다. 상품은 상품의 변형입니다. 카탈로그에서 제품은 범주별로 정렬되며 제품은 카탈로그에서 한 번 또는 여러 번 사용할 수 있습니다.Symfony3/Doctrine2 : QueryBuilder를 사용하는 InnerJoin을 사용한 하위 쿼리

카탈로그의 기사를 받고 싶지만 내 기사가 카탈로그에 직접 할당되지는 않으며 제품 만 있습니다.

나는 교리의 쿼리 빌더를 사용하여 다음과 같은 SQL을 구성하고 싶습니다 :

SELECT a.code, a.productCode, a.name 
FROM Article a 
INNER JOIN (
    SELECT p.code 
    FROM Product p 
    WHERE p.catalogCode = 'MYCODE' 
    GROUP BY p.code 
    ORDER BY p.code ASC 
) AS results ON results.productCode = a.productCode 

이 쿼리는 MySQL의에서 작동합니다. 내 기업의 저장소에서 작업을 수행하려고하지만 오류가 있습니다

public function findArticlesByCatalog($catatlogCode) 
{ 
    return $this->getEntityManager() 
     ->createQuery(
      'SELECT a.code, a.productCode, a.name 
       FROM AppBundle:Article a 
       INNER JOIN (
        SELECT p.code 
        FROM AppBundle:CatalogProduct p 
        WHERE p.catalogCode = :code 
        GROUP BY p.code 
        ORDER BY p.code ASC 
       ) AS results ON results.productCode = a.productCode' 
     ) 
     ->setParameter('code', $catatlogCode) 
     ->getResult(); 
} 

오류 (내부 조인 직후) : 그래서

[Semantical Error] line 0, col 81 near '(
SELECT': Error: Class '(' is not defined. 

를, 내가 사용하여 구축하고 싶습니다 내 컨트롤러에 Doctrine의 쿼리 빌더.

$repository = $em->getRepository('AppBundle:Article'); 

$qb = $repository->createQueryBuilder('a'); 
$qb->select(array('a.code', 'a.productCode', 'a.name')) 
    ->innerJoin(
     'AppBundle:CatalogProduct', 'p', 
     'WITH', 
     $qb->select('p.code') 
      ->where(
       $qb->expr()->eq('p.catalogCode', ':code') 
      ) 
      ->setParameter('code', $catCode) 
      ->groupBy('p.code') 
      ->orderBy('p.code', 'ASC') 
    ) 
// ... 

어떻게 쿼리의 나머지 부분을 지정합니다 ...

내가 뭔가를 시작하지만 난 그것을 완료 몰라?

AS results ON results.productCode = a.productCode' 

도움 주셔서 감사합니다.

+0

명곡하지만, 골디 : http://stackoverflow.com/questions/6637506/doing-a-where-in-subquery-in-doctrine-2 – LBA

+0

@LBA 고마워요.하지만 제 쿼리에 비해서는 이해가 잘 안됩니다. CatalogProduct 저장소를 사용하여 두 번째 쿼리 작성기를 만들고 해당 DQL을 얻어야합니까? 내 글을 업데이트했습니다. 내 쿼리의 'AS'및 'ON'부분에 문제가 있습니다. 제발 저에게 편지를 쓸 수 있습니까? – Felurian

답변

1

이 작업을 수행하는 올바른 방법을 찾았습니다.

쿼리 작성기로 쉽게 수행하기 위해 내 첫 번째 SQL을 다시 작성했습니다.

그래서, 내 첫 번째 SQL : 쿼리 빌더와

SELECT DISTINCT a.code, a.productCode, a.name 
FROM Article a 
JOIN Product p ON a.productCode = p.code 
WHERE p.code IN (
    SELECT p.code 
    FROM Product p 
    WHERE p.catalogCode = 'MYCODE' 
    GROUP BY p.code 
    ORDER BY p.code ASC 
) 

, 우리는 2 개의 다른 쿼리 빌더 2 개 쿼리를 작성해야합니다

SELECT a.code, a.productCode, a.name 
FROM Article a 
INNER JOIN (
    SELECT p.code 
    FROM Product p 
    WHERE p.catalogCode = 'MYCODE' 
    GROUP BY p.code 
    ORDER BY p.code ASC 
) AS cat_art ON cat_art.productCode = a.productCode 

...이 한 것과 같은 결과가 있습니다 :

# It is very important here to name it "p2", not "p" because, 
# in the main query, there is already "p" 
$qb2 = $em->getRepository('AppBundle:CatalogProduct')->createQueryBuilder('p2'); 

$subQuery = $qb2->select('p2.code') 
    ->where(
     $qb2->expr()->eq('p2.catalogCode', ':code') 
    ) 
    ->groupBy('p2.code') 
    ->orderBy('p2.code', 'ASC'); 

# main query 
$qb = $em->getRepository('AppBundle:Article')->createQueryBuilder('a'); 

$query = $qb->select(array('DISTINCT a.code', 'a.productCode', 'a.name', 'p.code AS productCode')) 
    ->join('AppBundle:CatalogProduct', 'p', 'WITH', 'a.productCode = p.code') 
    ->where(
     $qb->expr()->in(
      'p.code', 
      $subQuery->getDQL() 
     ) 
    ) 
    // Parameter used in subquery must be set in main query. 
    ->setParameter('code', $catCode) 
    ->getQuery();