2016-10-13 10 views
1

サブクエリの結合選択の結果をマップしようとすると、ネイティブクエリを作成するsymfonyとdoctrineに問題があります。私は元のための結合フィールドのnull結果を取得します。 ad.availabilityはnullです。Symfony Doctrineネイティブクエリ結果のマッピングサブクエリの選択select

基本的に私は2つのテーブルのactivityとactivity_datesを持っています。私は各活動の最低価格を取得する必要があります。 SQLが正しく動作します。しかしマッピングにはまった。

おかげ

$rsm = new ResultSetMapping; 
$rsm->addEntityResult('ActivityBundle:Activity', 'ac'); 
$rsm->addEntityResult('ActivityBundle:ActivityDate', 'ad'); 
$rsm->addFieldResult('ac', 'id', 'id'); 
$rsm->addFieldResult('ac', 'title', 'title'); 
$rsm->addFieldResult('ad','availability','availability'); 


$sql = 'SELECT 
      ac.id, 
      ac.title, 
      ac.price, 
      ad.availability 
     FROM 
      activities ac 
     LEFT JOIN 
      (SELECT 
       id, 
       date, 
       price, 
       activity_id, 
       availability 
      FROM 
       activity_dates a 
      WHERE 
       price = (
        SELECT 
         MIN(price) 
        FROM 
         activity_dates b 
        WHERE 
         b.activity_id = a.activity_id 
       ) 
      ) ad 
     ON 
      ad.activity_id = ac.id'; 


$query = $this->_em->createNativeQuery($sql, $rsm) 
    ->setHint(
     \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 
     'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker' 
    ) 
    ->setHint(
     \Gedmo\Translatable\TranslatableListener::HINT_INNER_JOIN, 
     true 
    ); 
+0

doctrineを手動で値を入力せずにクエリを実行すると、期待通りの結果が返されますか? – Chausser

+0

はいそうです。 SQLクエリは正しい値を返します。 – Never

答えて

0

のクエリを簡素化することから始めましょう:

SELECT ac.id, ac.title, ac.price, ad.availability 
FROM activities ac 
LEFT JOIN activity_dates ad 
    ON ad.activity_id = ac.id 
LEFT JOIN activity_dates ad2 
    ON ad2.activity_id = ad.activity_id 
     AND ad2.price < ad.price 
WHERE ad2.price IS NULL 

自己結合広告におけるよりも低い価格を持っているAD2からレコードをフェッチしようとしますactivity_datesへ。これはもちろん、広告の価格が利用可能な最低価格である場合には失敗するため、ac2のレコードは空になります。これはad2.price IS NULLによって結果を減らすために使用できる方法です。

わかりません:あなたの質問では、activity_datesの価格を比較しますが、活動の価格を選択してください。すべてのアクティビティで最低価格を求めたい場合は、activity_datesではなく、アクティビティの価格を比較する必要があります。または、最も安いactivity_dateが必要な場合は、代わりにad.priceを選択する必要があります。たぶんそれは単にタイプミスかもしれません...

とにかくこの簡略化されたクエリでは、あなたのエンティティを便利な方法で作成してから、doctrineのクエリ機能を使用するだけです。ここでカスタムクエリを実行する必要はありません。自己結合の参考のために

は、教義のマニュアルを参照してください。http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-one-self-referencing

それとも、このSOポスト: Doctrine 2 Self Join Query

基本的にはこのようなクエリに沸く(symfonyの3プロジェクトから採用します):

$query = $this->createQueryBuilder('ac'); 
$query->select('ac.id, ac.title, ac.price, ad.availability') 
    ->leftJoin('ac.activityDates', 'ad') 
    ->leftJoin('ad.selfJoin', 'ad2', Join::WITH, 'ad2.price < ad.price') 
    ->where(
     $query->expr()->isNull('ad2.price') 
    ); 
$result = $query->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY); 
+0

答えてくれてありがとう私はあなたに結果を教えてくれるでしょう。アクティビティと日付については、すべてのアクティビティが異なる日に異なる価格を持っています。 – Never

+0

この場合、個人的に私はad.priceを見たいと思っています。しかしそれはあなた次第であり、ごくわずかな変更だけです。単純化はそのトリックをしましたか? –

+0

@ノー:私の答えがあなたの問題解決に役立った場合は、それを受け入れられた回答とマークするか、少なくともアップアップしてください。それができなかった場合は、自由にコメントを追加してください。問題を解決するのに役立ちます。ありがとう。 –

関連する問題