11

I am new to Doctrine and I am trying to figure out how to add a having clause on my statement. Basically I want to be able to filter down on items returned based on how many attributes the user selects. The code is as follows:

// create query builder
    $qb = $this->getEntityManager()->createQueryBuilder();

    $qb->select('p')
        ->from($this->_entityName, 'p')
        ->leftJoin('p.options', 'o')
        ->where('p.active = :active')
        ->setParameter('active', 1);

    // add filters
     $qb->leftJoin('o.attributes', 'a');
                $ands = array();

                foreach ($value as $id => $values)
                { echo count($values);
                    $ands[] = $qb->expr()->andX(
                        $qb->expr()->eq('a.attribute_id', intval($id)),
                        $qb->expr()->in('a.attribute_value_id', array_map('intval', $values))
                        $qb->having('COUNT(*)=3) // THIS DOESN'T WORK
                        //$qb->expr()->having('COUNT(*)=3) // THIS DOESN'T WORK EITHER
                    );
                }

                $where = $qb->expr()->andX();


                foreach ($ands as $and)
                {
                    $where->add($and);
                }
                $qb->andWhere($where);
                $result = $qb->getQuery()->getResult();
                return $result;

When I try to execute the statement with the having() clause I get this error: Expression of type 'Doctrine\ORM\QueryBuilder' not allowed in this context.

Without the having() clause everything works perfectly.

I have no idea how to solve this.

4

3 回答 3

17

HAVING 子句需要一个 GROUP BY。在教义上,它会是这样的:

$qb->groupBy('p.id'); // or use an appropriate field
$qb->having('COUNT(*) = :some_count');
$qb->setParameter('some_count', 3);

假设您使用的是 mysql,这里有一个having子句教程:http ://www.mysqltutorial.org/mysql-having.aspx

于 2013-08-24T01:14:15.073 回答
1

也许您应该将数字 3 绑定到参数:

$qb->having('COUNT(*)=:some_count')
$qb->setParameter('some_count',3)
于 2013-08-23T14:00:00.500 回答
1

目标:向下过滤 在 O2M 关系的许多方面,我们想要过滤的一些已知可汇总条件(例如,捆绑中原始零件的数量)的一侧,我们想要限制一侧以及其他一些选择的标准。

然后我们为 LEFT_JOIN 操作添加一些条件:条件 #1 - bundle.id == original_part.bundle ID。条件 #2 - original_part 的 partStatusType == 3(一些硬编码值)。

然后我们过滤到 COUNT(op) >= 1,这给出了我们更有限的响应,在分页上工作得很好。

    $qb->leftJoin(OriginalPart::class, 'op', Expr\Join::WITH,
        $qb->expr()->andX(
            $qb->expr()->eq('op.bundle', 'row.id'),
            $qb->expr()->eq('op.partStatusType', 3)));
    $qb->groupBy('row.id');
    $qb->having($qb->expr()->gte('COUNT(op)', 1));

row 是 One(捆绑实体)的别名。

于 2017-04-19T19:49:07.130 回答