【问题标题】:Symfony2 - Doctrine2 QueryBuilder WHERE IN ManyToMany fieldSymfony2 - Doctrine2 QueryBuilder WHERE IN ManyToMany 字段
【发布时间】:2014-10-23 23:16:20
【问题描述】:

:)

提前感谢您帮助我解决这个问题:

我有一个实体 Hotel,它与实体 HotelService 具有多对多关系

我如何构建(如果可能,使用 QueryBuilder)一个查询来选择所有具有作为数组参数给出的服务子集的酒店?

示例:H1(S1, S2, S3, S4), H2(S2, S3, S4), H3(S1, S2, S3)

使用子集 (S1, S2) 查询必须返回 H1 和 H3。

我尝试了很多东西,这是一些代码摘录:

public function findByServices($services) {
 
    $qb = $this->createQueryBuilder('hotel')
 
            ->addSelect('location')
 
            ->addSelect('country')
 
            ->addSelect('billing')
 
            ->addSelect('services')
 
            ->innerJoin('hotel.billing', 'billing')
 
            ->innerJoin('hotel.location', 'location')
 
            ->innerJoin('location.city', 'city')
 
            ->innerJoin('location.country', 'country');
 
            ->innerJoin('hotel.services', 'services');
 
    $i = 0;
    $arrayIds = array();
    foreach ($services as $service) {
        $arrayIds[$i++] = $service->getId();
    }
    $qb->add('where', $qb->expr()->in('services', $arrayIds))->getQuery();
}

此代码返回在 $arrayIds 中有一个服务 ID 的所有酒店。

我想要相反的(服务包含 $arrayIds 中的所有 id 的酒店)。

当然,在 expr()->in 中取反参数并不能解决问题,并且会产生错误参数错误。

有人可以帮帮我吗? (对不起我的英语不好):)

【问题讨论】:

    标签: php mysql symfony doctrine-orm doctrine


    【解决方案1】:

    对于您的解决方案,您可以使用 COUNT(DISTINCT)HAVINGGROUP BY 子句

    public function findByServices($services)
    {
        $qb = $this->createQueryBuilder('hotel')
            ->addSelect('location')
            ->addSelect('country')
            ->addSelect('billing')
            ->addSelect('services')
            ->addSelect('COUNT(DISTINCT  services.id) AS total_services')
            ->innerJoin('hotel.billing', 'billing')
            ->innerJoin('hotel.location', 'location')
            ->innerJoin('location.city', 'city')
            ->innerJoin('location.country', 'country')
            ->innerJoin('hotel.services', 'services');
        $i = 0;
        $arrayIds = array();
        foreach ($services as $service) {
            $arrayIds[$i++] = $service->getId();
        }
        $qb->add('where', $qb->expr()->in('services', $arrayIds))
            ->addGroupBy('hotel.id')
            ->having('total_services = '.count($arrayIds))
            ->getQuery();
    }
    

    在上面的查询中,我又添加了一个选择来计算每个酒店的不同服务 ID,即

    ->addSelect('COUNT(DISTINCT services.id) AS HIDDEN total_services')

    然后我还需要一个分组依据,所以我添加了

    ->addGroupBy('hotel.id')


    现在棘手的部分来了,正如您提到的,您需要具有所有服务 ID(如 ids (1,2,3))的酒店,因此当我们在其执行或操作中使用时,应返回包含这 3 个服务的酒店,例如where servid_id = 1 or servid_id = 2 servid_id = 3 这正是你不希望酒店必须有这 3 个的 AND 操作所以我通过部分转换了这个逻辑

    ->having('total_services = '.count($arrayIds))

    现在total_services 是查询的虚拟别名,并保存每家酒店的不同计数,因此我将此计数与IN() 部分中提供的 ID 计数进行了比较,这将返回必须包含这些服务的酒店


    GROUP BY and HAVING Clause

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 2011-11-24
      • 2017-03-22
      • 1970-01-01
      相关资源
      最近更新 更多