2016-12-05 17 views
0

結合の複数のIDに基づいて選択をしようとしていますが、それぞれのIDは別の結合の別の条件と一致する必要があります。複数の条件に基づく結合からの選択

「ポジション」1または2に「Dichotomies」がすべて含まれている「タイプ」を取得する必要があります。現時点では、機能に渡されたディコトミーの1つに一致する結果が表示されますが、

$QB->select("Types","Types,ElementsPositions, Elements, Positions, Dichotomies, Quadras,TypesDescriptions,Relations") 
       ->from($this->get_repository()[0], 'Types'); 
       $QB->leftJoin("Types.ElementsPositions","ElementsPositions", \Doctrine\ORM\Query\Expr\Join::WITH, 'ElementsPositions.Positions = 1 OR ElementsPositions.Positions = 2'); 
       $QB->leftJoin("ElementsPositions.Elements","Elements"); 
       $QB->leftJoin("ElementsPositions.Positions","Positions"); 
       $QB->leftJoin("Elements.Dichotomies","Dichotomies"); 
       $QB->leftJoin("Types.Quadras","Quadras"); 
       $QB->leftJoin("Types.TypesDescriptions","TypesDescriptions"); 
       $QB->leftJoin("Types.Relations","Relations"); 

    if(!empty($where['dichotomies'])){ 
     foreach($where['dichotomies'] as $dichotomy){ 
       $QB->andWhere('Dichotomies.id'.'=:dichotomy'); 
       $QB->setParameter('dichotomy', $dichotomy['id']);     
     }    
    } 

UPD。 テーブルマッピング - JSONで:

{ 
"table-name": "types",  
"joins":[ 
    { 
     "table-name":"elements_positions", 
     "type":"one-to-many" 
    }, 
    { 
     "table-name":"quadras", 
     "type":"many-to-one" 
    }, 
    { 
     "table-name":"types_descriptions", 
     "type":"one-to-one" 
    }, 
    { 
     "table-name":"relations", 
     "type":"many-to-one" 
    } 
]} 

要素が

{ 
    "table-name": "elements_positions", 
    "joins":[ 
     { 
      "table-name":"elements", 
      "type":"many-to-one" 
     }, 
     { 
      "table-name":"positions", 
      "type":"many-to-one" 
     }, 
     { 
      "table-name":"types", 
      "type":"many-to-one" 
     } 
    ] 
} 

要素を位置決め

{ 
     "table-name": "elements",  
     "joins":[ 
      { 
       "table-name":"elements_positions", 
       "type":"one-to-many" 
      }, 
      { 
       "table-name":"quadras", 
       "type":"many-to-many" 
      }, 
      { 
       "table-name":"dichotomies", 
       "type":"many-to-many" 
      } 
     ] 
    } 

体位

"table-name": "positions",  
    "joins":[ 
     { 
      "table-name":"elements_positions", 
      "type":"one-to-many" 
     } 
    ] 
} 

二分法:

{ 
    "table-name": "dichotomies", 
    "joins":[ 
     { 
      "table-name":"elements", 
      "type":"many-to-many-inversed" 
     } 
    ] 
} 

答えて

1

クエリには2つの異なる問題があります。

まず、複数のパラメータ値が1つのパラメータでバインドされます。クエリ内のパラメータ:dichotomyの前の値は、$where['dichotomies']の次の要素で置換されます。 setParameters()メソッドは実際には準備されたステートメントに値をバインドしません。それは単にそれらをQueryBuilderオブジェクトに格納するだけです。したがって、foreachループの終了後、すべての条件は同じ値(最後は$where['dichotomies'])を使用します。異なるパラメータ名または数値インデックスを使用する必要がないようにするには

第二に、あなたは矛盾している条件を追加:$QB->andWhere()はそのような何かを生成します。

Dichotomies.id = :dichotomy 
AND Dichotomies.id = :dichotomy 
AND Dichotomies.id = :dichotomy 
... 

1つのエンティティIDは明らかに同時に異なる値に等しくすることができません。したがって、ANDOR演算子で置き換える必要があります。自動的setParameter()を呼び出す

は、あなたが値として設定されているタイプ推測:

しかし、良い方法はIN句を使用することです。これは整数の場合、の文字列/整数の配列、DateTimeインスタンス、および管理対象エンティティの場合に有効です。

ちょうど次の行でのforeachループを置き換える:

$QB->andWhere('Dichotomies.id IN (:dichotomies)'); 
$QB->setParameters('dichotomies', array_column($where['dichotomies'], 'id')); 

array_column()機能は、すべての二分法のIDのリストを返します。 Doctrineは式INを生成し、そのリストを使用してクエリプレースホルダを生成し、値をバインドします。

+0

ああ、確かに、setParameter()は毎回それを上書きしていました! しかし、Dichotomiesテーブルは、多対多の要素の逆の側です。要素は、Types、Elements、およびPositionsという3つの結合を持つElementsPositionsに対して1対多です。だからTypeはPosition 1と2に2つのDichotomies(要素を介して)を持つことができ、2つの$ 2分法でフィルタリングする必要があります - どちらも1または2の位置になければなりません。しかし、それはうまくいかない - 2つの二分法が送られてきても結果は得られません。もし私が "or"に変えれば、どちらかと一致する結果が得られます。 –

+0

申し訳ありませんが、理解するのは少し難しいです。あなたのクエリを編集し、取得したいネイティブSQLクエリを提供してもよいでしょうか? – Timurib

+0

私は純粋なSQLでそれを知っていれば恐れています。私は翻訳することができるでしょう。表 "Types"は "Type"の複数の "Dichotomies"と "Dichotomies"に "Positions"を持つことができます。私は、タイプ(Type)の両方の(2)「二分法」が「ポジション」1または2にあることを確認する必要があります。私はここで概念的に間違っていますか? –

関連する問題