2016-12-05 45 views
0

我想根据连接中的多个ID进行选择,每个ID都应该匹配另一个连接的另一个条件。根据多个条件从连接中选择主义

我需要获得“位置”1或2中包含所有“Dichotomies”的“类型”。目前,它给我的结果与传递给函数的二分法之一相匹配,但不是全部。

$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

您的查询有两个不同的问题。

首先,多个参数值绑定单个参数。 $where['dichotomies']的每个下一个元素将替换查询中参数:dichotomy的先前值。 setParameters()方法并不真正将值绑定到准备好的语句:它只是将它们存储在QueryBuilder对象中。因此,在foreach循环结束后,所有条件将使用相同的值(最后的$where['dichotomies'])。为了避免这种情况,您需要使用不同的参数名称或数字索引。

其次,添加互相矛盾的条件:$QB->andWhere()会产生类似的东西:

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

一个实体明显ID不能同时等于不同的值。因此,您需要由OR运营商替换AND

但更好的方法是使用IN条款:

调用setParameter()自动推断哪种类型要设置的值。这适用于整数,字符串/整数数组,DateTime实例和管理实体。

通过以下线路只需更换的foreach循环:

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

array_column()函数返回所有二分法ID的列表。 Doctrine生成IN表达式并使用该列表生成查询占位符并绑定这些值。

+0

哦,是的,setParameter()每次都是覆盖它! 但是Dichotomies表是元素的多对多的反面,元素对于ElementsPositions是一对多的,它有三个连接 - 类型,元素和位置。所以一个类型可以在位置1和2有两个二分法(通过元素),我需要通过提供的二元二分法过滤掉 - 两者都必须位于位置1或2.这就是为什么“和”不是“或”。但这不起作用 - 在发送两个二分法的情况下,我不会得到任何结果,如果我更改为“或”,则会得到与两个二分法相匹配的结果。 –

+0

对不起,但这有点难以理解。你可以编辑你的查询并提供你想要的原生SQL查询吗? – Timurib

+0

我害怕如果我知道它在纯SQL中,我将能够翻译。我想说什么,表“类型”可以有多个“类型”的“二分法”和“二分法”有“职位”。我需要检查“Type”的(2)“Dichotomies”是否在“Positions”1或2中。我在概念上错误吗? –