4

DQL を使用して、SQL で次のようなクエリを作成したいと考えています。

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');
4

1 に答える 1

0

FROMDQLの句にサブクエリを配置することはできません。

{uuid, locale}IRC であなたと話し合った時点で、あなたの PK は であると仮定します。クエリには 2 つの異なる列も含まれているため、これは醜いものになる可能性があります。あなたができることは、それを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 つのクエリビルダが関係しています!)

于 2012-10-31T21:17:32.507 に答える