2017-02-23 28 views
0

カタログには、製品と記事があります。商品は商品の変種です。 カタログでは、製品はカテゴリでソートされ、製品はカタログで1回または複数回使用できます。Symfony3/Doctrine2:QueryBuilderを使用したInnerJoinを使用したサブクエリ

カタログの記事を取得したいのですが、自分の記事がカタログに直接割り当てられていないため、商品のみが表示されます。

私はDoctrineのクエリビルダを使用して、次の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(); 
} 

はエラー(INNER JOINをした直後):

[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リポジトリを使用して2番目のクエリビルダを作成し、その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 

...は、この1と同じ結果があります。

# 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(); 
関連する問題