2017-02-23 124 views
0

在目錄中,我有產品和文章。文章是產品的變體。 在產品目錄中,產品按類別分類,產品可以在產品目錄中一次或多次。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的查詢生成器在我的Controller中。

我開始的東西,但我不知道去完成它......

$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執行相同的操作,以便使用查詢構建器輕鬆完成。

所以,我的第一個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 cat_art ON cat_art.productCode = a.productCode 

...具有相同的結果,這其中:

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個不同的查詢生成器:

# 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();