2012-03-08 49 views
6

tôi cần phải thực hiện truy vấn này:Symfony2 subquery trong Học thuyết quản lý tổ chức

SELECT * FROM (SELECT * FROM product WHERE car = 'large' ORDER BY onSale DESC) AS product_ordered GROUP BY type 

Trong Symfony2 bằng trình quản lý thực thể.

xây dựng truy vấn cơ bản của tôi sẽ là:

$query = $em->getRepository('AutomotiveBundle:Car') 
     ->createQueryBuilder('p') 
     ->where('pr.car = ?1') 
     ->andWhere('pr.status = 1') 
     ->orderBy('pr.onSale', 'DESC') 
     ->setParameter(1, $product->getName()) 
     ->groupBy('p.type') 
     ->getQuery(); 

Nhưng tôi không thể làm việc ra làm thế nào để thêm vào một subquery để này.

Ive đã cố gắng thực hiện một truy vấn riêng biệt và tham gia nó như:

->andWhere($query->expr()->in('pr.car = ?1',$query2->getQuery())); 

Nhưng tôi nhận được:

Call to undefined method Doctrine\ORM\Query::expr() 

Trả lời

8

Một Bí quyết là để xây dựng hai truy vấn và sau đó sử dụng getDQL() để nuôi đầu tiên truy vấn vào truy vấn thứ hai.

Ví dụ, truy vấn này trả về một danh sách riêng biệt của id trò chơi:

$qbGameId = $em->createQueryBuilder(); 

    $qbGameId->addSelect('distinct gameGameId.id'); 

    $qbGameId->from('ZaysoCoreBundle:Event','gameGameId'); 

    $qbGameId->leftJoin('gameGameId.teams','gameTeamGameId'); 

    if ($date1) $qbGameId->andWhere($qbGameId->expr()->gte('gameGameId.date',$date1)); 
    if ($date2) $qbGameId->andWhere($qbGameId->expr()->lte('gameGameId.date',$date2)); 

Bây giờ sử dụng DQL để có được thêm thông tin về các trò chơi bản thân:

$qbGames = $em->createQueryBuilder(); 

    $qbGames->addSelect('game'); 
    $qbGames->addSelect('gameTeam'); 
    $qbGames->addSelect('team'); 
    $qbGames->addSelect('field'); 

    $qbGames->addSelect('gamePerson'); 
    $qbGames->addSelect('person'); 

    $qbGames->from('ZaysoCoreBundle:Event','game'); 

    $qbGames->leftJoin('game.teams', 'gameTeam'); 
    $qbGames->leftJoin('game.persons', 'gamePerson'); 
    $qbGames->leftJoin('game.field', 'field'); 

    $qbGames->leftJoin('gameTeam.team',  'team'); 
    $qbGames->leftJoin('gamePerson.person', 'person'); 

    // Here is where we feed in the dql 
    $qbGames->andWhere($qbGames->expr()->in('game.id',$qbGameId->getDQL())); 

Kind của một tấm gương dài nhưng tôi không muốn chỉnh sửa nội dung và có thể phá vỡ nó.

+0

Tôi tin rằng giải pháp này được bỏ qua giới hạn về @cerad subquery. Ví dụ: $ qbGameId-> setMaxResults (20) và khi u in $ qbGames-> getDQL() u sẽ không thấy giới hạn truy vấn phụ. – EnchanterIO

+0

Một giải pháp khả thi: http://stackoverflow.com/questions/15877287/symfony2-doctrine-expr-subquery-error?answertab=active#tab-top – EnchanterIO

8

Bạn có thể sử dụng DBAL để thực hiện bất kỳ truy vấn sql nào.

$conn = $this->get('database_connection');//create a connection with your DB 

$sql="SELECT * FROM (SELECT * FROM product WHERE car =? ORDER BY onSale DESC) AS product_ordered GROUP BY type"; //Your sql Query     
$stmt = $conn->prepare($sql); // Prepare your sql 
$stmt->bindValue(1, 'large'); // bind your values ,if you have to bind another value, you need to write $stmt->bindValue(2, 'anothervalue'); but your order is important so on.. 
$stmt->execute(); //execute your sql 
$result=$stmt->fetchAll(); // fetch your result 

hạnh phúc mã hóa

+0

Đấu tranh để quyết định ai sẽ chấp nhận làm câu trả lời của tôi. Tôi thực sự đã đi với con đường này như nhỏ hơn của nó, nhưng nó không sử dụng Query Builder như Cerads câu trả lời. – BobFlemming

+0

Thx asish! và BTW chỉ là một mẹo nhỏ cho những người dùng khác chưa thành thạo trong symfony2 ... nếu bạn viết truy vấn này đã có trong kho lưu trữ thì kết nối bạn có thể nhận được thông qua $ conn = $ this -> _ em-> getConnection(); – EnchanterIO

+0

Vấn đề với giải pháp này là nó trả về dữ liệu thô thay vì đối tượng thực thể :( – Timwi

Các vấn đề liên quan