2017-02-22 35 views
1

我如何转换以下查询学说:如何做LeftJoin选择查询的QueryBuilder

SELECT restaurants.restaurant_name , 
      restaurants.restaurant_id, 
      j.LASTPRICE 
FROM  restaurants 


LEFT JOIN 
      ( 
        SELECT f.food_id              AS fid, 
           f.restaurants_restaurant_id          AS rid,        
           Max(f.food_last_price) AS LASTPRICE 
        FROM  foods               AS f 
        LEFT JOIN restaurants              AS r 
        ON  r.restaurant_id = f.restaurants_restaurant_id 
        WHERE  f.food_last_price IS NOT NULL      
        GROUP BY r.restaurant_id) j 
        ON restaurants.restaurant_id = j.rid 

这里是我的代码:

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

    $getMaxPercentage = $qb2 
     ->select(
      'MAX (Food.foodLastPrice) AS LASTPRICE ', 
      'Food.foodId AS fId', 
      'Food.restaurantsRestaurantId AS rID' 
     ) 
     ->from($this->entityClass,'Restaurant') 
     ->innerJoin('Restaurant.foods','Food') 
     ->where('Food.foodLastPrice IS NOT NULL') 
     ->groupBy('Restaurant.restaurantId') 
     ->getDQL(); 

    $restaurantList = $qb 
     ->select('Restaurants.restaurantName, Restaurants.restaurantId , j.LASTPRICE') 
     ->from($this->entityClass,'Restaurants') 
     ->leftJoin($getMaxPercentage,'j','WITH','Restaurants.restaurantId = j.rID') 
     ->getQuery()->execute(); 
    dd($restaurantList); 

我举一个错误:

SELECT Restaurants.restaurantName,': Error: Class 'SELECT' is not defined. 

我已经知道我可以在主查询中设置子查询,虽然在这种情况下我不想在Where中使用子查询exp ression。任何使用的建议select in LeftJoin in doctrine?

EDITED:我试过在我的查询中使用DQL:

$query = $this->_em->createQuery(
        ' 
         SELECT Restaurants.restaurantName , Restaurants.restaurantId 
         FROM App\\Restaurant AS Restaurants 
         LEFT JOIN (
          SELECT f.foodId AS fid, 
            f.restaurantsRestaurantId AS rid, 
            Max(f.foodLastPrice) AS LASTPRICE 
          FROM App\\Food AS f 
          LEFT JOIN App\\Restaurant AS r 
          WITH r.restaurantId = f.restaurantsRestaurantId 

          GROUP BY r.restaurantId) AS J 
         ON Restaurants.restaurantId = j.rid                                                 

        '); 

但我给了另一个错误:

[Semantical Error] Error: Class '(' is not defined. 

是否可以使用左选择加盟教义?

EDITED 2:我读了similar question和我决定以另一种方式来写:

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

    $subSelect = $qb2 
     ->select(
      array(
       'Food.foodLastPrice AS LASTPRICE ', 
       'Food.foodId AS fId', 
       'Food.restaurantsRestaurantId AS rId') 
     ) 
     ->from($this->entityClass,'Restaurant') 
     ->innerJoin('Restaurant.foods','Food') 
     ->where('Food.foodLastPrice IS NOT NULL') 
     ->groupBy('Restaurant.restaurantId') 
     ->getQuery()->getSQL(); 

    $restaurantList = 
     $qb->select(
      'Restaurant1' 
     ) 
      ->from($this->entityClass, 'Restaurant1') 
      ->leftJoin('Restaurant1',sprintf('(%s)',$subSelect),'internalQuery','Restaurant1.restaurantId = internalQuery.rId') 
      ->getQuery()->getSQL(); 
    dd($restaurantList); 

同样,我得到了一个错误:

near 'Restaurant1 (SELECT': Error: Class 'Restaurant1' is not defined. 
+1

对于复杂的查询,我正在使用Doctrine查询语言 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html – bxN5

+1

它在加入中不可能有子查询。如果你看看这个类的方法,它期望类名,而不是另一个查询。 可以将dql转换为sql,然后执行此查询。但这会鼓励这么多不好的做法,我甚至不会试图解释它。你最好的尝试将获得没有子查询的数据。是的,我可以看到该群组,但是您必须考虑您的业务案例并尝试以不同方式解决问题 – omxv

+0

@Roman我试图使用DQL。你可以再次检查我的问题吗? – AFN

回答

0

什么你想要做是不可能的:

https://github.com/doctrine/doctrine2/issues/3542(2013年11月,但学说概念自从和doctrinebot关闭后没有改变关闭这在2015年12月7日)

DQL is about querying objects. Supporting subselects in the FROM clause means that the DQL parser is not able to build the result set mapping anymore (as the fields returned by the subquery may not match the object anymore). This is why it cannot be supported (supporting it only for the case you run the query without the hydration is a no-go IMO as it would mean that the query parsing needs to be dependant of the execution mode).

In your case, the best solution is probably to run a SQL query instead (as you are getting a scalar, you don't need the ORM hydration anyway)

你可以找到解决方案像原始sql,或重新考虑你的查询。