我现在被困了12个小时。我的问题是根据XY参数构建过滤查询。
背景:
档案: 项目可以具有许多属性,每个属性仅与一个项目相关。
属性[id,type_id,value_id,item_id]:
情景:
在我列出项目的页面上,有属性过滤器
操作系统
Cpu Frequncy
当用户提交搜索表单时,我循环throug属性,并动态添加andWhere()。查询看起来像:
select .... from items i left join attributes a on i.id = a.item_id WHERE
a.type_id=typeid and a.value_id=valueid
当我这样做时只有1个参数,但是有2个参数
a.type_id=typeid AND a.value_id=valueid AND a.type_id=typeid AND a.value_id=valueid.....
结果为0
a.type_id=typeid AND a.value_id=valueid OR a.type_id=typeid AND a.value_id=valueid....
返回至少1个参数匹配的每个项目
我需要的是构建查询,以获得所有参数匹配的项目。像子查询循环一样,匹配第一个搜索属性而不是匹配结果匹配第二个,第三个,......最后得到项目的结果。
谢谢
-----编辑------
我继续,我正在创建像
这样的子查询$sAttrTypes = (isset($_GET["a"]) ? $_GET["a"] : array());
$qb = $this->em()->createQueryBuilder("p");
$qb->select(array("i", "a"))->from("ErikOfferBundle:Item", "i")->leftJoin("i.attributes", "a");
$i = 0;
$subquery_0 = false;
foreach ($sAttrTypes as $aTypeId => $aValues) {
if (!$aValues) {
continue;
}
$ids = false;
foreach ($aValues as $value) {
$ids[] = $value[0];
}
$query = $this->em()->createQueryBuilder("p_" . $i);
${"subquery_" . $i} = $query->select(array("i$i", "a$i"))
->from("ErikOfferBundle:Item", "i$i")
->leftJoin("i$i.attributes", "a$i");
if (count($ids) < 2) {
${"subquery_" . $i}->where($qb->expr()->eq("a$i.value", $ids[0]));
} else {
${"subquery_" . $i}->where($qb->expr()->in("a$i.value", $ids));
}
if ($i > 0) {
${"subquery_" . ($i - 1)}->andWhere($qb->expr()->in("i" . ($i - 1) . ".id", ${"subquery_" . $i}->getDql()));
}
echo "subquery_" . $i. ": " .${"subquery_" . $i}."<br/>";
$i++;
}
$qb->where($qb->expr()->in("i.id", ${"subquery_0"}->getDql()));
echo "Final query: " . $qb->getDql();
$items = $qb->getQuery()->getResult();
创建查询:
subquery_0: SELECT i0, a0 FROM ErikOfferBundle:Item i0 LEFT JOIN i0.attributes a0 WHERE a0.value = 1
subquery_1: SELECT i1, a1 FROM ErikOfferBundle:Item i1 LEFT JOIN i1.attributes a1 WHERE a1.value = 4
Final query: SELECT i, a FROM ErikOfferBundle:Item i LEFT JOIN i.attributes a WHERE i.id IN(SELECT i0, a0 FROM ErikOfferBundle:Item i0 LEFT JOIN i0.attributes a0 WHERE a0.value = 1 AND i0.id IN(SELECT i1, a1 FROM ErikOfferBundle:Item i1 LEFT JOIN i1.attributes a1 WHERE a1.value = 4))
它得到异常&#34; [语法错误]第0行,第88栏:错误:预期的Doctrine \ ORM \ Query \ Lexer :: T_FROM,得到了&#39;&#39;&#34; < / p>
col 88是&#34; i0,a0&#34;在第一个子查询中
答案 0 :(得分:1)
通过在子查询中仅选择1个表来解决
最终草案代码:
$sAttrTypes = (isset($_GET["a"]) ? $_GET["a"] : array());
$i = 0;
$subquery_0 = false;
foreach ($sAttrTypes as $aValues) {
if (!$aValues[1]) {
continue;
}
if (count($aValues) == 1 && ($aValues[1] == 0 || $aValues[1] == "")) {
continue;
}
$query = $this->em()->createQueryBuilder();
${"subquery_" . $i} = $query->select(array("i$i"))
->from("ErikOfferBundle:Item", "i$i")
->leftJoin("i$i.attributes", "a$i")
->where((count($aValues) == 1 ?
$query->expr()->eq("a$i.value", $aValues[1]) :
$query->expr()->in("a$i.value", $aValues)));
if ($i > 0) {
${"subquery_" . (0)}->andWhere($query->expr()->in("i0.id", ${"subquery_" . $i}->getDQL()));
}
$i++;
}
$qb = $this->em()->createQueryBuilder();
$qb->select(array("i", "a"))->from("ErikOfferBundle:Item", "i")->leftJoin("i.attributes", "a");
if ($subquery_0) {
$qb->andWhere($qb->expr()->in("i.id", $subquery_0->getDQL()));
}
$items = $qb->getQuery()->getResult();