Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Symfony2 - Doctrine2 QueryBuilder ONDE NO campo ManyToMany


Para sua solução, você pode usar COUNT(DISTINCT) com HAVING e GROUP BY cláusulas
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();
}

Na consulta acima, adicionei mais uma seleção contando IDs de serviço distintos para cada hotel, ou seja

Então eu também preciso de um grupo para essa contagem, então adicionei

Agora vem a parte complicada como você mencionou que você precisa de um hotel que tenha todos os ids de serviço como ids (1,2,3) para que os hotéis que contenham esses 3 serviços sejam retornados quando usarmos em seu desempenho ou operação como where servid_id = 1 or servid_id = 2 servid_id = 3 que é exatamente você não quer o AND operação que o hotel deve ter esses 3 então eu converti essa lógica tendo parte

Agora total_services é um alias virtual para a consulta e contém a contagem distinta para cada hotel, então comparei essa contagem com a contagem de IDs fornecidos em IN() parte isso devolverá os hotéis que devem conter esses serviços

GROUP BY and HAVING Clause