2012-10-31 52 views
4

我想用DQL創建一個查詢,看起來像這樣在SQL:子查詢中加入教義DQL

select 
    e.* 
from 
    e 
inner join (
    select 
     uuid, max(locale) as locale 
    from 
     e 
    where 
     locale = 'nl_NL' or 
     locale = 'nl' 
    group by 
     uuid 
) as e_ on e.uuid = e_.uuid and e.locale = e_.locale 

我試圖用的QueryBuilder生成查詢和子查詢。我認爲他們自己做了正確的事情,但我無法在聯合聲明中將它們結合起來。現在有人可以用DQL嗎?我不能使用本機SQL,因爲我想返回真實的對象,我不知道該查詢運行的是哪個對象(我只知道具有uuid和locale屬性的基類)。

$subQueryBuilder = $this->_em->createQueryBuilder(); 
    $subQueryBuilder 
     ->addSelect('e.uuid, max(e.locale) as locale') 
     ->from($this->_entityName, 'e') 
     ->where($subQueryBuilder->expr()->in('e.locale', $localeCriteria)) 
     ->groupBy('e.uuid'); 

    $queryBuilder = $this->_em->createQueryBuilder(); 
    $queryBuilder 
     ->addSelect('e') 
     ->from($this->_entityName, 'e') 
     ->join('('.$subQueryBuilder.') as', 'e_') 
     ->where('e.uuid = e_.uuid') 
     ->andWhere('e.locale = e_.locale'); 
+0

在子查詢上做一個INNER JOIN正是[我正在嘗試做的事情](http://stackoverflow.com/questions/27007090/inner-join-results-from-select-statement-using-doctrine -querybuilder)。你找到解決方案嗎? –

回答

0

您不能在DQL的FROM子句中放置子查詢。

我會假設你的PK是{uuid, locale},就像你在IRC上討論一樣。由於您的查詢中也有兩個不同的列,因此這可能會變得很難看。 你可以做的是將其放入WHERE條款:

select 
    e 
from 
    MyEntity e 
WHERE 
    e.uuid IN (
     select 
      e2.uuid 
     from 
      MyEntity e2 
     where 
      e2.locale IN (:selectedLocales) 
     group by 
      e2.uuid 
    ) 
    AND e.locale IN (
     select 
      max(e3.locale) as locale 
     from 
      MyEntity e3 
     where 
      e3.locale IN (:selectedLocales) 
     group by 
      e3.uuid 
    ) 

請注意,我用來對付你綁定到:selectedLocales語言環境的(非空)陣列的比較。這是爲了避免在需要與其他語言環境匹配時銷燬查詢緩存。

如果這樣做沒有真正的優勢,我也不會建議使用查詢構建器來構建它,因爲如果您動態添加條件,它將使查詢緩存變得更簡單(也包括3個查詢構建器參與! )

+0

我不認爲這會起作用,因爲結果中每行的uuid和語言環境之間沒有關係。 –

+0

是的,你是對的......這不會真的起作用。可能可以將'uuid'和'locale'字段串聯起來,然後進行檢查,但是在這種情況下任何密鑰都將毫無用處(而且這甚至不是一個好的解決方案) – Ocramius